brkraw 0.5.6__tar.gz → 0.5.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/workflows/release_on_merge.yml +29 -12
- {brkraw-0.5.6 → brkraw-0.5.7}/.markdownlint.yaml +1 -0
- brkraw-0.5.7/.vscode/settings.json +5 -0
- brkraw-0.5.7/.vscode/tasks.json +86 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/CITATION.cff +1 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/PKG-INFO +3 -3
- {brkraw-0.5.6 → brkraw-0.5.7}/README.md +2 -2
- brkraw-0.5.7/RELEASE_NOTES.md +15 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/__init__.py +1 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/addon/dependencies.py +84 -8
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/hook/core.py +21 -2
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/core.py +3 -6
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/scan.yaml +4 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/study.yaml +2 -2
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/convert.py +12 -3
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/hook.py +14 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/info.py +1 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/prune.py +1 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/utils.py +11 -3
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/affine.py +28 -2
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/addon.md +12 -8
- brkraw-0.5.7/docs/api/convert.md +218 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/data-access.md +8 -2
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/hook.md +38 -7
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/info.md +22 -7
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/layout.md +38 -12
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/overview.md +27 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/api/prune.md +27 -29
- brkraw-0.5.7/docs/assets/gif/intro.gif +0 -0
- brkraw-0.5.7/docs/cli/addon.md +106 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/cli/cache.md +3 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/cli/config.md +1 -0
- brkraw-0.5.7/docs/cli/convert.md +276 -0
- brkraw-0.5.7/docs/cli/hook.md +129 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/cli/index.md +14 -0
- brkraw-0.5.7/docs/cli/info.md +75 -0
- brkraw-0.5.7/docs/cli/init.md +69 -0
- brkraw-0.5.7/docs/cli/params.md +79 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/cli/prune.md +12 -1
- brkraw-0.5.7/docs/cli/session.md +216 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/cli-extensions.md +30 -5
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/contributing.md +4 -4
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/contributors.md +1 -1
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/documentation.md +5 -6
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/hook-packages.md +34 -17
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/roadmap.md +29 -30
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/addons-and-plugins.md +13 -0
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/cli-extensions.md +5 -1
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/context-map.md +4 -4
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/extensibility.md +3 -3
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/hook-packages.md +1 -1
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/layout.md +14 -11
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/rules.md +29 -21
- {brkraw-0.5.6/docs/reference → brkraw-0.5.7/docs/extensions}/specs.md +87 -41
- brkraw-0.5.7/docs/getting-started/api.md +217 -0
- brkraw-0.5.7/docs/getting-started/bids.md +126 -0
- brkraw-0.5.7/docs/getting-started/cli.md +214 -0
- brkraw-0.5.6/docs/getting-started/configuration.md → brkraw-0.5.7/docs/getting-started/config.md +6 -57
- brkraw-0.5.7/docs/getting-started/gui.md +25 -0
- brkraw-0.5.7/docs/getting-started/index.md +76 -0
- brkraw-0.5.7/docs/index.md +18 -0
- brkraw-0.5.7/docs/stylesheets/extra.css +69 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/mkdocs.yml +19 -19
- {brkraw-0.5.6 → brkraw-0.5.7}/pyproject.toml +1 -0
- brkraw-0.5.7/tests/test_03_resolver/test_affine.py +75 -0
- brkraw-0.5.7/tests/test_apps/test_addon_dependencies.py +91 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_cli/test_hook_preset.py +13 -0
- brkraw-0.5.6/.vscode/settings.json +0 -4
- brkraw-0.5.6/.vscode/tasks.json +0 -86
- brkraw-0.5.6/RELEASE_NOTES.md +0 -14
- brkraw-0.5.6/docs/api/convert.md +0 -316
- brkraw-0.5.6/docs/cli/addon.md +0 -171
- brkraw-0.5.6/docs/cli/convert.md +0 -316
- brkraw-0.5.6/docs/cli/hook.md +0 -190
- brkraw-0.5.6/docs/cli/info.md +0 -126
- brkraw-0.5.6/docs/cli/session.md +0 -117
- brkraw-0.5.6/docs/getting-started/api.md +0 -148
- brkraw-0.5.6/docs/getting-started/backup.md +0 -10
- brkraw-0.5.6/docs/getting-started/bids.md +0 -19
- brkraw-0.5.6/docs/getting-started/cli.md +0 -136
- brkraw-0.5.6/docs/getting-started/hooks.md +0 -127
- brkraw-0.5.6/docs/getting-started/index.md +0 -89
- brkraw-0.5.6/docs/getting-started/mrs.md +0 -10
- brkraw-0.5.6/docs/getting-started/viewer.md +0 -15
- brkraw-0.5.6/docs/index.md +0 -101
- brkraw-0.5.6/docs/stylesheets/extra.css +0 -23
- brkraw-0.5.6/tests/test_03_resolver/test_affine.py +0 -32
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/DISCUSSION_TEMPLATE/proposal.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/DISCUSSION_TEMPLATE/question.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/copilot-instructions.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/workflows/ci.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/workflows/docs.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/workflows/publish.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.github/workflows/release.yml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/.gitignore +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/AGENTS.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/CODE_OF_CONDUCT.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/CONTRIBUTING.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/LICENSE +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/api/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/api/types.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/addon/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/addon/core.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/addon/installation.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/addon/io.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/hook/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/formatter.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/helper.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/scan.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/study.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/info/transform.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/apps/loader/types.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/addon.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/cache.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/config.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/init.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/params.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/commands/session.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/hook_args.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/cli/main.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/cache.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/config.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/entrypoints.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/formatter.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/fs.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/jcamp.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/layout.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/parameters.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/core/zip.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/dataclasses/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/dataclasses/node.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/dataclasses/reco.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/dataclasses/scan.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/dataclasses/study.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/default/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/default/pruner_specs/deid4share.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/default/rules/00_default.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/default/specs/metadata_dicom.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/default/specs/metadata_transforms.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/datatype.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/fid.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/helpers.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/image.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/nifti.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/resolver/shape.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/context_map.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/meta.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/niftiheader.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/pruner.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/remapper.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/schema/rules.yaml +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/hook/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/hook/logic.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/hook/validator.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/meta/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/meta/validator.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/pruner/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/pruner/logic.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/pruner/validator.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/remapper/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/remapper/logic.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/remapper/validator.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/rules/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/rules/logic.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/brkraw/specs/rules/validator.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/brkraw-logo-dark.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/brkraw-logo-light.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/brkraw-logo.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-16.png +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-192.png +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-32.png +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-512.png +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-dark.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon-light.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon.ico +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/favicon.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/site.webmanifest +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/assets/zenodo_badge.svg +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/dev/core-vs-addon.md +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/overrides/404.html +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/docs/overrides/partials/extrahead.html +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/release_pr.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/release_prep.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/tag_and_push.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/update_contributors.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/update_readme_bibtex.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/scripts/update_zenodo_badge.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/conftest.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/helpers.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/__init__.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/fixtures/acqp_EPI_pv5_1.jdx +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/fixtures/method_EPI_pv5_1.jdx +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/fixtures/method_FLASH_pv360_3_1.jdx +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_formatter.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_fs.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_jcamp.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_parameters.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_resources.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_01_core/test_zip.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_02_dataclasses/test_dir-vs-zipped.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_04_specs/test_context_map_cases.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_04_specs/test_remapper.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_apps/test_affine_post_transform.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_apps/test_loader_info_missing_visu_pars.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_cli/test_hook_args_yaml.py +0 -0
- {brkraw-0.5.6 → brkraw-0.5.7}/tests/test_scripts/test_update_contributors.py +0 -0
|
@@ -3,6 +3,19 @@ name: Release On Merge
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
tag:
|
|
9
|
+
description: "Tag to create and push (e.g., v0.4.2)"
|
|
10
|
+
required: true
|
|
11
|
+
run_release:
|
|
12
|
+
description: "Trigger release workflow after tagging"
|
|
13
|
+
required: false
|
|
14
|
+
default: "true"
|
|
15
|
+
type: choice
|
|
16
|
+
options:
|
|
17
|
+
- "true"
|
|
18
|
+
- "false"
|
|
6
19
|
|
|
7
20
|
permissions:
|
|
8
21
|
contents: write
|
|
@@ -29,12 +42,6 @@ jobs:
|
|
|
29
42
|
# Default outputs
|
|
30
43
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
31
44
|
|
|
32
|
-
# Only proceed for merge commits ("Merge pull request ...")
|
|
33
|
-
if [[ "${{ github.event.head_commit.message }}" != Merge\ pull\ request* ]]; then
|
|
34
|
-
echo "Not a merge commit. Skipping."
|
|
35
|
-
exit 0
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
45
|
# Find the PR associated with this merge commit and ensure it has the 'release' label.
|
|
39
46
|
api="https://api.github.com/repos/${REPO}/commits/${SHA}/pulls"
|
|
40
47
|
pr_json=$(curl -fsSL \
|
|
@@ -59,7 +66,8 @@ jobs:
|
|
|
59
66
|
)
|
|
60
67
|
|
|
61
68
|
if [[ -z "${pr_number}" ]]; then
|
|
62
|
-
echo "No PR associated with ${SHA}. Skipping."
|
|
69
|
+
echo "No PR associated with ${SHA}. Skipping."
|
|
70
|
+
echo "This can happen for direct pushes, API failures, or insufficient token scopes."
|
|
63
71
|
exit 0
|
|
64
72
|
fi
|
|
65
73
|
|
|
@@ -79,7 +87,8 @@ jobs:
|
|
|
79
87
|
)
|
|
80
88
|
|
|
81
89
|
if [[ "${has_release}" != "true" ]]; then
|
|
82
|
-
echo "PR #${pr_number} does not have 'release' label. Skipping."
|
|
90
|
+
echo "PR #${pr_number} does not have 'release' label. Skipping."
|
|
91
|
+
echo "If this was a squash/rebase merge, ensure the PR is labeled before merging."
|
|
83
92
|
exit 0
|
|
84
93
|
fi
|
|
85
94
|
|
|
@@ -107,10 +116,18 @@ jobs:
|
|
|
107
116
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
108
117
|
echo "value=$version" >> "$GITHUB_OUTPUT"
|
|
109
118
|
shell: bash
|
|
119
|
+
- name: Manual tag inputs
|
|
120
|
+
id: manual
|
|
121
|
+
if: ${{ github.event_name == 'workflow_dispatch' }}
|
|
122
|
+
run: |
|
|
123
|
+
set -euo pipefail
|
|
124
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
125
|
+
echo "value=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
|
|
126
|
+
echo "run_release=${{ inputs.run_release }}" >> "$GITHUB_OUTPUT"
|
|
110
127
|
- name: Create and push tag
|
|
111
|
-
if: ${{ steps.version.outputs.changed == 'true' }}
|
|
128
|
+
if: ${{ steps.version.outputs.changed == 'true' || steps.manual.outputs.changed == 'true' }}
|
|
112
129
|
run: |
|
|
113
|
-
tag="${{ steps.version.outputs.value }}"
|
|
130
|
+
tag="${{ steps.manual.outputs.value || steps.version.outputs.value }}"
|
|
114
131
|
if git rev-parse "$tag" >/dev/null 2>&1; then
|
|
115
132
|
echo "Tag $tag already exists. Skipping."
|
|
116
133
|
exit 0
|
|
@@ -118,9 +135,9 @@ jobs:
|
|
|
118
135
|
git tag "$tag" "${{ github.sha }}"
|
|
119
136
|
git push origin "$tag"
|
|
120
137
|
- name: Trigger release workflow
|
|
121
|
-
if: ${{ steps.version.outputs.changed == 'true' }}
|
|
138
|
+
if: ${{ (steps.version.outputs.changed == 'true') || (steps.manual.outputs.changed == 'true' && steps.manual.outputs.run_release == 'true') }}
|
|
122
139
|
env:
|
|
123
140
|
GH_TOKEN: ${{ github.token }}
|
|
124
141
|
run: |
|
|
125
|
-
tag="${{ steps.version.outputs.value }}"
|
|
142
|
+
tag="${{ steps.manual.outputs.value || steps.version.outputs.value }}"
|
|
126
143
|
gh workflow run release.yml -f tag="$tag"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"id": "releaseVersion",
|
|
6
|
+
"type": "promptString",
|
|
7
|
+
"description": "Release version (e.g., 1.0.0)"
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"tasks": [
|
|
11
|
+
{
|
|
12
|
+
"label": "Standard: Setup venv + deps",
|
|
13
|
+
"type": "shell",
|
|
14
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" -m venv .venv && \"${workspaceFolder}/.venv/bin/python\" -m pip install -U pip && \"${workspaceFolder}/.venv/bin/python\" -m pip install -e \".[dev]\"",
|
|
15
|
+
"windows": {
|
|
16
|
+
"command": "\"${workspaceFolder}\\.venv\\Scripts\\python\" -m venv .venv; \"${workspaceFolder}\\.venv\\Scripts\\python\" -m pip install -U pip; \"${workspaceFolder}\\.venv\\Scripts\\python\" -m pip install -e \".[dev]\"",
|
|
17
|
+
"options": {
|
|
18
|
+
"shell": {
|
|
19
|
+
"executable": "pwsh"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"group": "build",
|
|
24
|
+
"problemMatcher": []
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"label": "Standard: Release Prep PR (2-step)",
|
|
28
|
+
"type": "shell",
|
|
29
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/release_pr.py --version ${input:releaseVersion} --base upstream/main --remote-upstream upstream --remote-origin origin",
|
|
30
|
+
"group": "build",
|
|
31
|
+
"problemMatcher": []
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"label": "DryRun: Release Prep PR (2-step)",
|
|
35
|
+
"type": "shell",
|
|
36
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/release_pr.py --dry-run --version ${input:releaseVersion} --base upstream/main --remote-upstream upstream --remote-origin origin",
|
|
37
|
+
"group": "build",
|
|
38
|
+
"problemMatcher": []
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"label": "Standard: MkDocs Serve",
|
|
42
|
+
"type": "shell",
|
|
43
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" -m mkdocs serve",
|
|
44
|
+
"group": "build",
|
|
45
|
+
"problemMatcher": []
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"label": "Optional: Release Prep (bump + notes)",
|
|
49
|
+
"type": "shell",
|
|
50
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/update_contributors.py --source github --repo brkraw/brkraw --output docs/dev/contributors.md && \"${workspaceFolder}/.venv/bin/python\" scripts/release_prep.py --version ${input:releaseVersion} --fetch-tags --remote upstream",
|
|
51
|
+
"windows": {
|
|
52
|
+
"command": "pwsh -NoProfile -Command \"& \\\"${workspaceFolder}\\.venv\\Scripts\\python\\\" scripts/update_contributors.py --source github --repo brkraw/brkraw --output docs/dev/contributors.md; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; & \\\"${workspaceFolder}\\.venv\\Scripts\\python\\\" scripts/release_prep.py --version ${input:releaseVersion} --fetch-tags --remote upstream\""
|
|
53
|
+
},
|
|
54
|
+
"group": "build",
|
|
55
|
+
"problemMatcher": []
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"label": "Optional: Release Notes Only",
|
|
59
|
+
"type": "shell",
|
|
60
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/release_notes.py --fetch-tags --remote upstream",
|
|
61
|
+
"group": "build",
|
|
62
|
+
"problemMatcher": []
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"label": "Optional: Release Tag + Push (upstream)",
|
|
66
|
+
"type": "shell",
|
|
67
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/tag_and_push.py",
|
|
68
|
+
"group": "build",
|
|
69
|
+
"problemMatcher": []
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"label": "Optional: Docs Update Contributors (git)",
|
|
73
|
+
"type": "shell",
|
|
74
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/update_contributors.py --source git --output docs/dev/contributors.md",
|
|
75
|
+
"group": "build",
|
|
76
|
+
"problemMatcher": []
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"label": "Optional: Docs Update Contributors (GitHub API)",
|
|
80
|
+
"type": "shell",
|
|
81
|
+
"command": "\"${workspaceFolder}/.venv/bin/python\" scripts/update_contributors.py --source github --repo brkraw/brkraw --output docs/dev/contributors.md",
|
|
82
|
+
"group": "build",
|
|
83
|
+
"problemMatcher": []
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brkraw
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.7
|
|
4
4
|
Summary: Toolkit for loading Bruker Paravision datasets, mapping metadata, and exporting NIfTI
|
|
5
5
|
Project-URL: Homepage, https://brkraw.github.io
|
|
6
6
|
Maintainer-email: SungHo Lee <shlee@unc.edu>
|
|
@@ -49,7 +49,7 @@ Description-Content-Type: text/markdown
|
|
|
49
49
|
|
|
50
50
|
A modular toolkit for Bruker MRI raw-data handling.
|
|
51
51
|
|
|
52
|
-
BrkRaw (v0.5.
|
|
52
|
+
BrkRaw (v0.5.7) converts raw data into standardized, neuroimaging-ready
|
|
53
53
|
datasets, with extensible rules/specs and plugin hooks.
|
|
54
54
|
|
|
55
55
|
- Documentation: [brkraw.github.io](https://brkraw.github.io/)
|
|
@@ -70,7 +70,7 @@ If you use BrkRaw in your research, please cite it.
|
|
|
70
70
|
@software{brkraw,
|
|
71
71
|
author = {Lee, Sung-Ho and Devenyi, Gabriel A. and Ban, Woomi and Shih, Yen-Yu Ian},
|
|
72
72
|
title = {BrkRaw: A modular toolkit for Bruker MRI raw-data handling},
|
|
73
|
-
version = {0.5.
|
|
73
|
+
version = {0.5.7},
|
|
74
74
|
doi = {10.5281/zenodo.3818614},
|
|
75
75
|
url = {https://github.com/BrkRaw/brkraw},
|
|
76
76
|
note = {Documentation: https://brkraw.github.io},
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
A modular toolkit for Bruker MRI raw-data handling.
|
|
12
12
|
|
|
13
|
-
BrkRaw (v0.5.
|
|
13
|
+
BrkRaw (v0.5.7) converts raw data into standardized, neuroimaging-ready
|
|
14
14
|
datasets, with extensible rules/specs and plugin hooks.
|
|
15
15
|
|
|
16
16
|
- Documentation: [brkraw.github.io](https://brkraw.github.io/)
|
|
@@ -31,7 +31,7 @@ If you use BrkRaw in your research, please cite it.
|
|
|
31
31
|
@software{brkraw,
|
|
32
32
|
author = {Lee, Sung-Ho and Devenyi, Gabriel A. and Ban, Woomi and Shih, Yen-Yu Ian},
|
|
33
33
|
title = {BrkRaw: A modular toolkit for Bruker MRI raw-data handling},
|
|
34
|
-
version = {0.5.
|
|
34
|
+
version = {0.5.7},
|
|
35
35
|
doi = {10.5281/zenodo.3818614},
|
|
36
36
|
url = {https://github.com/BrkRaw/brkraw},
|
|
37
37
|
note = {Documentation: https://brkraw.github.io},
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Release v0.5.7
|
|
2
|
+
|
|
3
|
+
Date: 2026-02-03
|
|
4
|
+
Changes since 0.5.6
|
|
5
|
+
|
|
6
|
+
- docs: release notes for v0.5.7 (0fbaf73)
|
|
7
|
+
- chore: prepare release v0.5.7 (3e98477)
|
|
8
|
+
- docs: update contributors (3f18c3b)
|
|
9
|
+
- doc: markdown lint (2fde999)
|
|
10
|
+
- Fix hook spec documentation (5c271e1)
|
|
11
|
+
- update (dev): CI workflow / dev configurations (502c98a)
|
|
12
|
+
- patch(info_spec): added missing slice info (13fbc3e)
|
|
13
|
+
- fix(cli): ensure to make outout directory during convertion (6dfb153)
|
|
14
|
+
- Fix hook uninstall deps, affine slicepacks, and info stdout (da01975)
|
|
15
|
+
- fix (spec): typo in Study info spec (ef6c980)
|
|
@@ -17,11 +17,23 @@ RULE_KEYS = {"info_spec", "metadata_spec", "converter_hook"}
|
|
|
17
17
|
_SPEC_EXTS = (".yaml", ".yml")
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def warn_dependencies(
|
|
20
|
+
def warn_dependencies(
|
|
21
|
+
target: Path,
|
|
22
|
+
*,
|
|
23
|
+
kind: str,
|
|
24
|
+
root: Optional[Union[str, Path]],
|
|
25
|
+
ignore_rules_dir: Optional[Path] = None,
|
|
26
|
+
ignore_specs_dir: Optional[Path] = None,
|
|
27
|
+
) -> bool:
|
|
21
28
|
paths = config_core.paths(root=root)
|
|
22
29
|
warned = False
|
|
23
30
|
if kind == "spec":
|
|
24
|
-
used_by_rules = rules_using_spec(
|
|
31
|
+
used_by_rules = rules_using_spec(
|
|
32
|
+
target,
|
|
33
|
+
paths.rules_dir,
|
|
34
|
+
root=paths.root,
|
|
35
|
+
ignore_dir=ignore_rules_dir,
|
|
36
|
+
)
|
|
25
37
|
if used_by_rules:
|
|
26
38
|
logger.warning(
|
|
27
39
|
"Spec %s is referenced by rules: %s",
|
|
@@ -29,7 +41,11 @@ def warn_dependencies(target: Path, *, kind: str, root: Optional[Union[str, Path
|
|
|
29
41
|
", ".join(sorted(used_by_rules)),
|
|
30
42
|
)
|
|
31
43
|
warned = True
|
|
32
|
-
included_by = specs_including_spec(
|
|
44
|
+
included_by = specs_including_spec(
|
|
45
|
+
target,
|
|
46
|
+
paths.specs_dir,
|
|
47
|
+
ignore_dir=ignore_specs_dir,
|
|
48
|
+
)
|
|
33
49
|
if included_by:
|
|
34
50
|
logger.warning(
|
|
35
51
|
"Spec %s is included by: %s",
|
|
@@ -54,12 +70,34 @@ def warn_dependencies(target: Path, *, kind: str, root: Optional[Union[str, Path
|
|
|
54
70
|
return warned
|
|
55
71
|
|
|
56
72
|
|
|
57
|
-
def
|
|
73
|
+
def _is_under(path: Path, base: Optional[Path]) -> bool:
|
|
74
|
+
if base is None:
|
|
75
|
+
return False
|
|
76
|
+
try:
|
|
77
|
+
path.relative_to(base)
|
|
78
|
+
except ValueError:
|
|
79
|
+
return False
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def rules_using_spec(
|
|
84
|
+
target: Union[str, Path],
|
|
85
|
+
rules_dir: Path,
|
|
86
|
+
*,
|
|
87
|
+
root: Optional[Union[str, Path]] = None,
|
|
88
|
+
ignore_dir: Optional[Path] = None,
|
|
89
|
+
) -> Set[str]:
|
|
58
90
|
used_by: Set[str] = set()
|
|
59
91
|
if not rules_dir.exists():
|
|
60
92
|
return used_by
|
|
93
|
+
if isinstance(target, Path):
|
|
94
|
+
target_path = target.resolve()
|
|
95
|
+
else:
|
|
96
|
+
target_path = None
|
|
61
97
|
files = list(rules_dir.rglob("*.yaml")) + list(rules_dir.rglob("*.yml"))
|
|
62
98
|
for path in files:
|
|
99
|
+
if _is_under(path, ignore_dir):
|
|
100
|
+
continue
|
|
63
101
|
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
64
102
|
if not isinstance(data, dict):
|
|
65
103
|
continue
|
|
@@ -70,17 +108,46 @@ def rules_using_spec(spec_name: str, rules_dir: Path) -> Set[str]:
|
|
|
70
108
|
if not isinstance(item, dict):
|
|
71
109
|
continue
|
|
72
110
|
use = item.get("use")
|
|
73
|
-
if isinstance(use, str)
|
|
111
|
+
if not isinstance(use, str):
|
|
112
|
+
continue
|
|
113
|
+
if target_path is None:
|
|
114
|
+
if Path(use).name == str(target):
|
|
115
|
+
used_by.add(path.name)
|
|
116
|
+
continue
|
|
117
|
+
if root is None:
|
|
118
|
+
continue
|
|
119
|
+
version = item.get("version") if isinstance(item.get("version"), str) else None
|
|
120
|
+
try:
|
|
121
|
+
resolved = resolve_spec_reference(
|
|
122
|
+
use,
|
|
123
|
+
category=key,
|
|
124
|
+
version=version,
|
|
125
|
+
root=root,
|
|
126
|
+
)
|
|
127
|
+
except Exception:
|
|
128
|
+
continue
|
|
129
|
+
if resolved.resolve() == target_path:
|
|
74
130
|
used_by.add(path.name)
|
|
75
131
|
return used_by
|
|
76
132
|
|
|
77
133
|
|
|
78
|
-
def specs_including_spec(
|
|
134
|
+
def specs_including_spec(
|
|
135
|
+
target: Union[str, Path],
|
|
136
|
+
specs_dir: Path,
|
|
137
|
+
*,
|
|
138
|
+
ignore_dir: Optional[Path] = None,
|
|
139
|
+
) -> Set[str]:
|
|
79
140
|
included_by: Set[str] = set()
|
|
80
141
|
if not specs_dir.exists():
|
|
81
142
|
return included_by
|
|
143
|
+
if isinstance(target, Path):
|
|
144
|
+
target_path = target.resolve()
|
|
145
|
+
else:
|
|
146
|
+
target_path = None
|
|
82
147
|
files = list(specs_dir.rglob("*.yaml")) + list(specs_dir.rglob("*.yml"))
|
|
83
148
|
for path in files:
|
|
149
|
+
if _is_under(path, ignore_dir):
|
|
150
|
+
continue
|
|
84
151
|
data = yaml.safe_load(path.read_text(encoding="utf-8"))
|
|
85
152
|
if not isinstance(data, dict):
|
|
86
153
|
continue
|
|
@@ -92,8 +159,17 @@ def specs_including_spec(spec_name: str, specs_dir: Path) -> Set[str]:
|
|
|
92
159
|
include_list = [include]
|
|
93
160
|
elif isinstance(include, list) and all(isinstance(item, str) for item in include):
|
|
94
161
|
include_list = include
|
|
95
|
-
|
|
96
|
-
|
|
162
|
+
for item in include_list:
|
|
163
|
+
inc_path = Path(item)
|
|
164
|
+
if not inc_path.is_absolute():
|
|
165
|
+
inc_path = (path.parent / inc_path).resolve()
|
|
166
|
+
if target_path is None:
|
|
167
|
+
if inc_path.name == str(target):
|
|
168
|
+
included_by.add(path.name)
|
|
169
|
+
break
|
|
170
|
+
elif inc_path == target_path:
|
|
171
|
+
included_by.add(path.name)
|
|
172
|
+
break
|
|
97
173
|
return included_by
|
|
98
174
|
|
|
99
175
|
|
|
@@ -150,12 +150,18 @@ def uninstall_hook(
|
|
|
150
150
|
"transforms": [],
|
|
151
151
|
}
|
|
152
152
|
root_path = config_core.resolve_root(root)
|
|
153
|
+
namespace = entry.get("namespace") if isinstance(entry, dict) else None
|
|
153
154
|
for kind in ("specs", "pruner_specs", "rules", "transforms"):
|
|
154
155
|
for relpath in entry.get(kind, []) if isinstance(entry, dict) else []:
|
|
155
156
|
target_path = root_path / relpath
|
|
156
157
|
if not target_path.exists():
|
|
157
158
|
continue
|
|
158
|
-
if _has_dependencies(
|
|
159
|
+
if _has_dependencies(
|
|
160
|
+
target_path,
|
|
161
|
+
kind,
|
|
162
|
+
root=root_path,
|
|
163
|
+
namespace=namespace,
|
|
164
|
+
) and not force:
|
|
159
165
|
raise RuntimeError("Dependencies found; use --force to remove.")
|
|
160
166
|
target_path.unlink()
|
|
161
167
|
removed[kind].append(relpath)
|
|
@@ -587,9 +593,22 @@ def _has_dependencies(
|
|
|
587
593
|
kind: str,
|
|
588
594
|
*,
|
|
589
595
|
root: Optional[Union[str, Path]],
|
|
596
|
+
namespace: Optional[str] = None,
|
|
590
597
|
) -> bool:
|
|
591
598
|
try:
|
|
592
|
-
|
|
599
|
+
ignore_rules_dir = None
|
|
600
|
+
ignore_specs_dir = None
|
|
601
|
+
if namespace:
|
|
602
|
+
paths = config_core.paths(root=root)
|
|
603
|
+
ignore_rules_dir = paths.rules_dir / namespace
|
|
604
|
+
ignore_specs_dir = paths.specs_dir / namespace
|
|
605
|
+
return addon_deps.warn_dependencies(
|
|
606
|
+
target,
|
|
607
|
+
kind=_kind_to_remove(kind),
|
|
608
|
+
root=root,
|
|
609
|
+
ignore_rules_dir=ignore_rules_dir,
|
|
610
|
+
ignore_specs_dir=ignore_specs_dir,
|
|
611
|
+
)
|
|
593
612
|
except Exception:
|
|
594
613
|
return False
|
|
595
614
|
|
|
@@ -565,7 +565,6 @@ class BrukerLoader:
|
|
|
565
565
|
|
|
566
566
|
if scope == 'scan':
|
|
567
567
|
if not as_dict:
|
|
568
|
-
config_core.configure_logging(root=base, stream=sys.stdout)
|
|
569
568
|
text = format_info_tables(
|
|
570
569
|
{"Scan(s)": scan_info},
|
|
571
570
|
width=width,
|
|
@@ -574,7 +573,7 @@ class BrukerLoader:
|
|
|
574
573
|
scan_transpose=scan_transpose,
|
|
575
574
|
float_decimals=float_decimals,
|
|
576
575
|
)
|
|
577
|
-
|
|
576
|
+
print(text)
|
|
578
577
|
return None
|
|
579
578
|
return scan_info
|
|
580
579
|
|
|
@@ -586,19 +585,17 @@ class BrukerLoader:
|
|
|
586
585
|
|
|
587
586
|
if scope == 'study':
|
|
588
587
|
if not as_dict:
|
|
589
|
-
config_core.configure_logging(root=base, stream=sys.stdout)
|
|
590
588
|
text = format_info_tables(
|
|
591
589
|
study_info,
|
|
592
590
|
width=width,
|
|
593
591
|
float_decimals=float_decimals,
|
|
594
592
|
)
|
|
595
|
-
|
|
593
|
+
print(text)
|
|
596
594
|
return None
|
|
597
595
|
return study_info
|
|
598
596
|
|
|
599
597
|
study_info['Scan(s)'] = scan_info
|
|
600
598
|
if not as_dict:
|
|
601
|
-
config_core.configure_logging(root=base, stream=sys.stdout)
|
|
602
599
|
text = format_info_tables(
|
|
603
600
|
study_info,
|
|
604
601
|
width=width,
|
|
@@ -607,7 +604,7 @@ class BrukerLoader:
|
|
|
607
604
|
scan_transpose=scan_transpose,
|
|
608
605
|
float_decimals=float_decimals,
|
|
609
606
|
)
|
|
610
|
-
|
|
607
|
+
print(text)
|
|
611
608
|
return None
|
|
612
609
|
return study_info
|
|
613
610
|
|
|
@@ -5,7 +5,7 @@ study:
|
|
|
5
5
|
description: "Study-level info mapping for Bruker datasets."
|
|
6
6
|
category: "info_spec"
|
|
7
7
|
transforms_source: "transform.py"
|
|
8
|
-
Study.
|
|
8
|
+
Study.Operator:
|
|
9
9
|
sources:
|
|
10
10
|
- file: subject
|
|
11
11
|
key: SUBJECT_referral
|
|
@@ -91,7 +91,7 @@ scan:
|
|
|
91
91
|
description: "Scan-level fallback info mapping for Bruker datasets."
|
|
92
92
|
category: "info_spec"
|
|
93
93
|
transforms_source: "transform.py"
|
|
94
|
-
Study.
|
|
94
|
+
Study.Operator:
|
|
95
95
|
sources:
|
|
96
96
|
- file: visu_pars
|
|
97
97
|
key: VisuStudyReferringPhysician
|
|
@@ -12,7 +12,7 @@ import logging
|
|
|
12
12
|
import os
|
|
13
13
|
import re
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
from typing import Any, Mapping, Optional, Dict, List, Tuple, cast, get_args
|
|
15
|
+
from typing import Any, Mapping, Optional, Dict, List, Tuple, Sequence, cast, get_args
|
|
16
16
|
|
|
17
17
|
import numpy as np
|
|
18
18
|
from brkraw.cli.utils import load
|
|
@@ -387,6 +387,8 @@ def cmd_convert(args: argparse.Namespace) -> int:
|
|
|
387
387
|
for path in output_paths:
|
|
388
388
|
reserved_paths.add(path)
|
|
389
389
|
|
|
390
|
+
_ensure_output_dirs(output_paths)
|
|
391
|
+
|
|
390
392
|
sidecar_meta = None
|
|
391
393
|
if args.sidecar:
|
|
392
394
|
sidecar_meta = loader.get_metadata(
|
|
@@ -397,12 +399,10 @@ def cmd_convert(args: argparse.Namespace) -> int:
|
|
|
397
399
|
|
|
398
400
|
if args.no_convert:
|
|
399
401
|
for path in output_paths:
|
|
400
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
401
402
|
_write_sidecar(path, sidecar_meta)
|
|
402
403
|
total_written += 1
|
|
403
404
|
else:
|
|
404
405
|
for path, obj in zip(output_paths, nii_list):
|
|
405
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
406
406
|
obj.to_filename(str(path))
|
|
407
407
|
logger.info("Wrote NIfTI: %s", path)
|
|
408
408
|
total_written += 1
|
|
@@ -713,6 +713,15 @@ def _parse_hook_args(values: List[str]) -> Dict[str, Dict[str, Any]]:
|
|
|
713
713
|
return parsed
|
|
714
714
|
|
|
715
715
|
|
|
716
|
+
def _ensure_output_dirs(paths: Sequence[Path]) -> None:
|
|
717
|
+
for path in paths:
|
|
718
|
+
try:
|
|
719
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
720
|
+
except OSError as exc:
|
|
721
|
+
logger.error("Failed to create output directory %s: %s", path.parent, exc)
|
|
722
|
+
raise
|
|
723
|
+
|
|
724
|
+
|
|
716
725
|
def _uses_counter_tag(
|
|
717
726
|
*,
|
|
718
727
|
layout_template: Optional[str],
|
|
@@ -274,7 +274,8 @@ def cmd_preset(args: argparse.Namespace) -> int:
|
|
|
274
274
|
return 2
|
|
275
275
|
preset = _infer_hook_preset(entry)
|
|
276
276
|
payload = {"hooks": {args.target: preset}}
|
|
277
|
-
|
|
277
|
+
normalized = _normalize_yaml_payload(payload)
|
|
278
|
+
text = yaml.safe_dump(normalized, sort_keys=False)
|
|
278
279
|
if args.output:
|
|
279
280
|
Path(args.output).expanduser().write_text(text, encoding="utf-8")
|
|
280
281
|
logger.info("Wrote preset: %s", args.output)
|
|
@@ -283,6 +284,18 @@ def cmd_preset(args: argparse.Namespace) -> int:
|
|
|
283
284
|
return 0
|
|
284
285
|
|
|
285
286
|
|
|
287
|
+
def _normalize_yaml_payload(value: Any) -> Any:
|
|
288
|
+
if isinstance(value, Path):
|
|
289
|
+
return str(value)
|
|
290
|
+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
|
291
|
+
return _normalize_yaml_payload(dataclasses.asdict(value))
|
|
292
|
+
if isinstance(value, dict):
|
|
293
|
+
return {key: _normalize_yaml_payload(item) for key, item in value.items()}
|
|
294
|
+
if isinstance(value, (list, tuple, set)):
|
|
295
|
+
return [_normalize_yaml_payload(item) for item in value]
|
|
296
|
+
return value
|
|
297
|
+
|
|
298
|
+
|
|
286
299
|
def register(subparsers: argparse._SubParsersAction) -> None: # type: ignore[name-defined]
|
|
287
300
|
hook_parser = subparsers.add_parser(
|
|
288
301
|
"hook",
|
|
@@ -97,7 +97,7 @@ def register(subparsers: argparse._SubParsersAction) -> None: # type: ignore[na
|
|
|
97
97
|
"--output",
|
|
98
98
|
dest="output",
|
|
99
99
|
type=str,
|
|
100
|
-
help="Output zip path (default:
|
|
100
|
+
help="Output zip path (default: ./<root_name>.zip when omitted).",
|
|
101
101
|
)
|
|
102
102
|
prune_parser.add_argument(
|
|
103
103
|
"--no-validate",
|
|
@@ -7,6 +7,7 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
import itertools
|
|
9
9
|
import logging
|
|
10
|
+
import sys
|
|
10
11
|
import threading
|
|
11
12
|
import time
|
|
12
13
|
from contextlib import contextmanager
|
|
@@ -26,7 +27,7 @@ def spinner(prefix: str = "Loading") -> Iterator[None]:
|
|
|
26
27
|
Yields:
|
|
27
28
|
None.
|
|
28
29
|
"""
|
|
29
|
-
if logger.isEnabledFor(logging.DEBUG):
|
|
30
|
+
if logger.isEnabledFor(logging.DEBUG) or not sys.stdout.isatty():
|
|
30
31
|
yield
|
|
31
32
|
return
|
|
32
33
|
|
|
@@ -35,7 +36,11 @@ def spinner(prefix: str = "Loading") -> Iterator[None]:
|
|
|
35
36
|
|
|
36
37
|
def run() -> None:
|
|
37
38
|
while not stop_event.is_set():
|
|
38
|
-
|
|
39
|
+
try:
|
|
40
|
+
print(f"\r{prefix} {next(seq)}", end="", flush=True)
|
|
41
|
+
except BrokenPipeError:
|
|
42
|
+
stop_event.set()
|
|
43
|
+
break
|
|
39
44
|
time.sleep(0.08)
|
|
40
45
|
|
|
41
46
|
thread = threading.Thread(target=run, daemon=True)
|
|
@@ -45,7 +50,10 @@ def spinner(prefix: str = "Loading") -> Iterator[None]:
|
|
|
45
50
|
finally:
|
|
46
51
|
stop_event.set()
|
|
47
52
|
thread.join()
|
|
48
|
-
|
|
53
|
+
try:
|
|
54
|
+
print("\r" + " " * (len(prefix) + 2) + "\r", end="", flush=True)
|
|
55
|
+
except BrokenPipeError:
|
|
56
|
+
pass
|
|
49
57
|
|
|
50
58
|
|
|
51
59
|
def load(path, *, prefix: str = "Loading") -> BrukerLoader:
|