From 5986937295812408d1488d32dd73d943ceae831d Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 22:42:47 +0200 Subject: [PATCH 01/19] update docs --- docs/.gitignore | 1 + docs/README.md | 4 ++-- docs/source/conf.py | 11 ++++++----- docs/source/index.rst | 11 +++++++++-- 4 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 docs/.gitignore diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 910c208..a35d655 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,8 +3,8 @@ ## Set up virtual environment ```bash -virtualenv -p python3 your_repo_name -source your_repo_name/bin/activate +virtualenv -p python3.8 env +source env/bin/activate pip install -r requirements.txt ``` diff --git a/docs/source/conf.py b/docs/source/conf.py index d05d57b..b4c2ccd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -17,12 +17,11 @@ # -- Project information ----------------------------------------------------- -project = 'your repo name' -copyright = 'you' -author = 'you' +project = 'spm_2_bids' +author = 'RĂ©mi Gau' # The full version, including alpha/beta/rc tags -release = 'v0.0.0' +release = 'v0.1.0' # -- General configuration --------------------------------------------------- @@ -53,6 +52,8 @@ # source_suffix = ['.rst', '.md'] source_suffix = '.rst' +autodoc_member_order = 'bysource' + # -- Options for HTML output ------------------------------------------------- @@ -64,7 +65,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +# html_static_path = ['_static'] # html_logo = '_static/logo.png' diff --git a/docs/source/index.rst b/docs/source/index.rst index d452f33..7170e79 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,7 +1,7 @@ .. cpp_bids documentation master file -Welcome to CPP BIDS documentation! -********************************** +Welcome to spm_2_bids documentation! +************************************ .. toctree:: :maxdepth: 2 @@ -12,11 +12,18 @@ Welcome to CPP BIDS documentation! ``spm_2_bids`` only provides names to use but does not actually rename the files. .. automodule:: src + .. autofunction:: spm_2_bids .. automodule:: src.defaults + .. autofunction:: check_cfg +.. autoclass:: Mapping + :members: + + + Indices and tables ================== From 022cb256f5fe1b220a6f8cd0a184e06ee45d4ca3 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 22:43:25 +0200 Subject: [PATCH 02/19] set up binder, notebooks and infra --- binder/apt.txt | 5 + binder/environment.yml | 2 + binder/postBuild | 12 +++ examples/.gitignore | 1 + examples/demo.ipynb | 237 +++++++++++++++++++++++++++++++++++++++++ miss_hit.cfg | 9 +- requirements.txt | 12 +-- 7 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 binder/apt.txt create mode 100644 binder/environment.yml create mode 100644 binder/postBuild create mode 100644 examples/.gitignore create mode 100644 examples/demo.ipynb diff --git a/binder/apt.txt b/binder/apt.txt new file mode 100644 index 0000000..23b6a54 --- /dev/null +++ b/binder/apt.txt @@ -0,0 +1,5 @@ +octave +liboctave-dev +gnuplot +ghostscript +tree diff --git a/binder/environment.yml b/binder/environment.yml new file mode 100644 index 0000000..19c10f8 --- /dev/null +++ b/binder/environment.yml @@ -0,0 +1,2 @@ +dependencies: +- octave_kernel diff --git a/binder/postBuild b/binder/postBuild new file mode 100644 index 0000000..7e769e8 --- /dev/null +++ b/binder/postBuild @@ -0,0 +1,12 @@ +cd ${HOME} + +octave --no-gui --no-window-system --silent --eval "addpath (getenv (\"HOME\")); savepath ();" +octave --no-gui --no-window-system --silent --eval "addpath (fullfile (getenv (\"HOME\"), \"+bids\")); savepath ();" + +git clone git://github.com/gllmflndn/JSONio.git --depth 1 +cd JSONio; mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS; cd .. + +octave --no-gui --no-window-system --silent --eval "addpath (fullfile (getenv (\"HOME\"), \"JSONio\")); savepath ();" + +cd ${HOME}/examples + diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..58461f2 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +.ipynb_checkpoints \ No newline at end of file diff --git a/examples/demo.ipynb b/examples/demo.ipynb new file mode 100644 index 0000000..c23a573 --- /dev/null +++ b/examples/demo.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a4c07e0c-8673-4fa8-bc31-800409fb09c4", + "metadata": {}, + "source": [ + "# SPM_2_BIDS DEMO\n", + "\n", + "**Helping you convert your SPM output into a BIDS compliant datasets.**\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "68482373-0288-4920-99a6-68e7db8bac44", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Correct matlab/octave verions and added to the path!\n" + ] + } + ], + "source": [ + "run ../init_spm_2_bids.m" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0d1179df-bfa6-494c-a900-ab667d6bfa5d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sub-01_T1w_seg8.mat\t-->\tsub-01_label-T1w_segparam.mat\n", + "sub-01_task-auditory_bold_uw.mat\t-->\tsub-01_task-auditory_label-bold_unwarpparam.mat\n", + "y_sub-01_T1w.nii\t-->\tsub-01_from-T1w_to-IXI549Space_mode-image_xfm.nii\n", + "iy_sub-01_T1w.nii\t-->\tsub-01_from-IXI549Space_to-T1w_mode-image_xfm.nii\n", + "y_sub-01_T2w.nii\t-->\tsub-01_from-T2w_to-IXI549Space_mode-image_xfm.nii\n", + "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "c1sub-01_T1w.nii\t-->\tsub-01_space-individual_label-GM_probseg.nii\n", + "c2sub-01_T1w.nii\t-->\tsub-01_space-individual_label-WM_probseg.nii\n", + "c3sub-01_T1w.nii\t-->\tsub-01_space-individual_label-CSF_probseg.nii\n", + "msub-01_T1w.nii\t-->\tsub-01_space-individual_desc-biascor_T1w.nii\n", + "wmsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", + "wsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", + "wc1sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-GM_probseg.nii\n", + "wc2sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-WM_probseg.nii\n", + "wc3sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-CSF_probseg.nii\n", + "asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-stc_bold.nii\n", + "usub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii\n", + "rp_sub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", + "rp_asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", + "meansub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "meanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "meanuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "wsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wmeanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-mean_bold.nii\n", + "swsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "ssub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "suasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "srsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "srasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n" + ] + } + ], + "source": [ + "input_files = { 'sub-01_T1w_seg8.mat'; ...\n", + " 'sub-01_task-auditory_bold_uw.mat'; ...\n", + " 'y_sub-01_T1w.nii'; ...\n", + " 'iy_sub-01_T1w.nii'; ...\n", + " 'y_sub-01_T2w.nii'; ...\n", + " 'susub-01_task-auditory_bold.nii'; ...\n", + " 'swuasub-01_task-auditory_bold.nii'; ...\n", + " 'c1sub-01_T1w.nii'; ... \n", + " 'c2sub-01_T1w.nii'; ... \n", + " 'c3sub-01_T1w.nii'; ... \n", + " 'msub-01_T1w.nii'; ... \n", + " 'wmsub-01_T1w.nii'; ... \n", + " 'wsub-01_T1w.nii'; ...\n", + " 'wc1sub-01_T1w.nii'; ... \n", + " 'wc2sub-01_T1w.nii'; ... \n", + " 'wc3sub-01_T1w.nii'; ... \n", + " 'asub-01_task-auditory_bold.nii'; ...\n", + " 'usub-01_task-auditory_bold.nii'; ...\n", + " 'rp_sub-01_task-auditory_bold.nii'; ... \n", + " 'rp_asub-01_task-auditory_bold.nii'; ...\n", + " 'meansub-01_task-auditory_bold.nii'; ... \n", + " 'meanusub-01_task-auditory_bold.nii'; ... \n", + " 'meanuasub-01_task-auditory_bold.nii'; ...\n", + " 'wsub-01_task-auditory_bold.nii'; ... \n", + " 'wuasub-01_task-auditory_bold.nii'; ... \n", + " 'wusub-01_task-auditory_bold.nii'; ... \n", + " 'wrsub-01_task-auditory_bold.nii'; ... \n", + " 'wrasub-01_task-auditory_bold.nii'; ...\n", + " 'wmeanusub-01_task-auditory_bold.nii'; ...\n", + " 'swsub-01_task-auditory_bold.nii'; ... \n", + " 'swuasub-01_task-auditory_bold.nii'; ... \n", + " 'swusub-01_task-auditory_bold.nii'; ... \n", + " 'swrsub-01_task-auditory_bold.nii'; ... \n", + " 'swrasub-01_task-auditory_bold.nii'; ...\n", + " 'ssub-01_task-auditory_bold.nii'; ... \n", + " 'suasub-01_task-auditory_bold.nii'; ... \n", + " 'susub-01_task-auditory_bold.nii'; ... \n", + " 'srsub-01_task-auditory_bold.nii'; ... \n", + " 'srasub-01_task-auditory_bold.nii'; ...\n", + "};\n", + " \n", + "\n", + "for i = 1:size(input_files, 1)\n", + "\n", + " filename = spm_2_bids(input_files{i, 1});\n", + " \n", + " fprintf(1, '%s\\t-->\\t%s\\n', input_files{i, 1}, filename);\n", + "\n", + "end" + ] + }, + { + "cell_type": "markdown", + "id": "cdb56e9a-3757-45a6-ba5a-c1228f478a3e", + "metadata": {}, + "source": [ + "# Override the default name map" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "547873ea-d673-4338-998e-a10ea80b1682", + "metadata": {}, + "outputs": [], + "source": [ + "map = Mapping();\n", + "\n", + "map = map.default();\n", + "\n", + "name_spec = map.cfg.preproc_norm;\n", + "name_spec.entities.res = '1pt0';\n", + "map = map.add_mapping('prefix', 'wm', ...\n", + " 'suffix', 'T1w', ...\n", + " 'ext', '.nii', ...\n", + " 'entities', struct('desc', 'skullstripped'), ...\n", + " 'name_spec', name_spec);\n", + "\n", + "name_spec = struct('suffix', 'T1w', ...\n", + " 'ext', '.gii', ...\n", + " 'entities', struct('desc', 'pialsurf'));\n", + "map = map.add_mapping('prefix', 'c1', ...\n", + " 'suffix', 'T1w', ...\n", + " 'ext', '.surf.gii', ...\n", + " 'entities', '*', ... % allows any entity, if empty only prefix is used\n", + " 'name_spec', name_spec);\n", + "\n", + "map = map.flatten_mapping();\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "6dde6430-e419-4771-8a61-1b5ba6d362d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "c1sub-01_T1w.surf.gii\t-->\tsub-01_desc-pialsurf_T1w.gii\n", + "wmsub-01_desc-skullstripped_T1w.nii\t-->\tsub-01_space-IXI549Space_res-1pt0_desc-preproc_T1w.nii\n", + "wmsub-01_desc-skullstripped_T2w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T2w.nii\n", + "wmsub-01_desc-preproc_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n" + ] + } + ], + "source": [ + "input_output = {'c1sub-01_T1w.surf.gii'; ... % new mapping for surface data\n", + " 'wmsub-01_desc-skullstripped_T1w.nii'; ... % new mapping for skulltripped data\n", + " 'wmsub-01_desc-skullstripped_T2w.nii'; ... % wrong suffix: use only prefix\n", + " 'wmsub-01_desc-preproc_T1w.nii'; ... % wrong entity: use only prefix\n", + " };\n", + "\n", + "for i = 1:size(input_output, 1)\n", + "\n", + " filename = spm_2_bids(input_output{i, 1}, map);\n", + " \n", + " fprintf(1, '%s\\t-->\\t%s\\n', input_output{i, 1}, filename);\n", + "\n", + "end" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Octave", + "language": "octave", + "name": "octave" + }, + "language_info": { + "file_extension": ".m", + "help_links": [ + { + "text": "GNU Octave", + "url": "https://www.gnu.org/software/octave/support.html" + }, + { + "text": "Octave Kernel", + "url": "https://github.com/Calysto/octave_kernel" + }, + { + "text": "MetaKernel Magics", + "url": "https://metakernel.readthedocs.io/en/latest/source/README.html" + } + ], + "mimetype": "text/x-octave", + "name": "octave", + "version": "4.2.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/miss_hit.cfg b/miss_hit.cfg index 5d969f8..bb56875 100644 --- a/miss_hit.cfg +++ b/miss_hit.cfg @@ -4,15 +4,16 @@ project_root line_length: 100 regex_function_name: "[a-z]+(_[a-z0-9]+)*" -regex_script_name: "[a-z]+(_[a-z0-9]+)*" -# regex_parameter_name: "[a-z]+(_[a-z0-9]+)*" +regex_class_name: "[A-Z]{1}[a-z]+" +regex_script_name: "[a-z]+(_[a-z]+)*" +regex_parameter_name: "[a-z]+(_[a-z0-9]+)*" exclude_dir: "lib" copyright_entity: "spm_2_bids developers" # metric for code quality -metric "cnest": limit 6 +metric "cnest": limit 5 metric "file_length": limit 500 -metric "cyc": limit 25 +metric "cyc": limit 15 metric "parameters": limit 5 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 667fbf6..9e5839c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -Sphinx -sphinxcontrib-matlabdomain -sphinxcontrib-napoleon -sphinx_rtd_theme -miss_hit==0.9.22 -pre-commit \ No newline at end of file +miss_hit==0.9.26 +pre-commit +jupyterlab +octave_kernel +jinja2 +-r docs/requirements.txt \ No newline at end of file From 2fcaa6ee3d1c0d3622a1ed9018370957cac0772e Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 22:53:34 +0200 Subject: [PATCH 03/19] update code --- init_env.m => init_spm_2_bids.m | 4 ++-- miss_hit.cfg | 4 +++- requirements.txt | 2 +- src/defaults/Mapping.m | 36 +++++++++++++++--------------- src/defaults/check_cfg.m | 2 +- src/defaults/get_spm_prefix_list.m | 13 ++++++++++- src/spm_2_bids.m | 8 +++---- tests/test_spm_2_bids.m | 5 +++-- 8 files changed, 44 insertions(+), 30 deletions(-) rename init_env.m => init_spm_2_bids.m (96%) diff --git a/init_env.m b/init_spm_2_bids.m similarity index 96% rename from init_env.m rename to init_spm_2_bids.m index fdaa191..acf5564 100644 --- a/init_env.m +++ b/init_spm_2_bids.m @@ -1,4 +1,4 @@ -function init_env +function init_spm_2_bids % % 1 - Check if version requirements % are satisfied and the packages are @@ -18,7 +18,7 @@ OCTAVE_VER = '4.0.3'; MATLAB_VER = '8.6.0'; - INSTALL_LIST = {'io', 'statistics', 'image'}; + INSTALL_LIST = {}; if is_octave diff --git a/miss_hit.cfg b/miss_hit.cfg index bb56875..78ada53 100644 --- a/miss_hit.cfg +++ b/miss_hit.cfg @@ -6,7 +6,9 @@ line_length: 100 regex_function_name: "[a-z]+(_[a-z0-9]+)*" regex_class_name: "[A-Z]{1}[a-z]+" regex_script_name: "[a-z]+(_[a-z]+)*" -regex_parameter_name: "[a-z]+(_[a-z0-9]+)*" + +# suppress_rule: "naming_parameters" +# regex_parameter_name: "[a-z]+(_[a-z0-9]+)*" exclude_dir: "lib" diff --git a/requirements.txt b/requirements.txt index 9e5839c..0723c45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -miss_hit==0.9.26 +miss_hit==0.9.27 pre-commit jupyterlab octave_kernel diff --git a/src/defaults/Mapping.m b/src/defaults/Mapping.m index b631bee..b0259a3 100644 --- a/src/defaults/Mapping.m +++ b/src/defaults/Mapping.m @@ -3,28 +3,28 @@ % Creates a mapping object that will contain the list how an spm file will be renamed % into a bids derivatives. % - % Has the following attributes:: + % Has the following attributes: % - % - mapping : (n X 1) structure with the following fiels + % - mapping, (n X 1) structure with the following fields: % - % - prefix - % - suffix - % - entities - % - ext - % - name_spec: structure that must resemble the output of bids.internal.parse_filename + % - ``prefix`` + % - ``suffix`` + % - ``entities`` + % - ``ext`` + % - ``name_spec``: structure that must resemble the output of bids.File % - % - cfg : describes the common properties to be used for several names in the output. - % See ``check_cfg`` + % - cfg describes the common properties to be used for several names in the output. + % (See ``check_cfg()``) % - % - list of SPM prefixes from ``get_spm_prefix_list()`` + % - list of SPM prefixes from ``get_spm_prefix_list()``: % - % - stc = '' - % - realign = '' - % - unwarp = '' - % - coreg = '' - % - bias_cor = '' - % - norm = '' - % - smooth = '' + % - ``stc = ''`` + % - ``realign = ''`` + % - ``unwarp = ''`` + % - ``coreg = ''`` + % - ``bias_cor = ''`` + % - ``norm = ''`` + % - ``smooth = ''`` % % (C) Copyright 2021 spm_2_bids developers @@ -91,7 +91,7 @@ % map = add_mapping('prefix', prefix, 'suffix', 'entities', 'ext', 'name_spec') % - % TODO add possibility to pass "filter" arugment that is a structure + % TODO add possibility to pass "filter" argument that is a structure % with shape (allows to chain the output from bids parsing) % % filter.prefix diff --git a/src/defaults/check_cfg.m b/src/defaults/check_cfg.m index e12bc0a..f514c89 100644 --- a/src/defaults/check_cfg.m +++ b/src/defaults/check_cfg.m @@ -5,7 +5,7 @@ % % USAGE:: % - % cfg = check_cfg(cfg) + % cfg = check_cfg(cfg) % % :param cfg: structure or json filename containing the spm_2_bids.anat. % :type cfg: structure diff --git a/src/defaults/get_spm_prefix_list.m b/src/defaults/get_spm_prefix_list.m index ea9fef3..2ce68c7 100644 --- a/src/defaults/get_spm_prefix_list.m +++ b/src/defaults/get_spm_prefix_list.m @@ -5,7 +5,18 @@ % % (C) Copyright 2021 spm_2_bids developers - spm_defaults = spm_get_defaults(); + try + spm_defaults = spm_get_defaults(); + catch + spm_defaults.slicetiming.prefix = 's'; + spm_defaults.realign.write.prefix = 'r'; + spm_defaults.unwarp.write.prefix = 'u'; + spm_defaults.coreg.write.prefix = 'r'; + spm_defaults.deformations.modulate.prefix = 'm'; + spm_defaults.normalise.write.prefix = 'w'; + spm_defaults.smooth.prefix = 's'; + end + prefix_list.stc = spm_defaults.slicetiming.prefix; prefix_list.realign = spm_defaults.realign.write.prefix; prefix_list.unwarp = spm_defaults.unwarp.write.prefix; diff --git a/src/spm_2_bids.m b/src/spm_2_bids.m index fa8bf35..0d28c85 100644 --- a/src/spm_2_bids.m +++ b/src/spm_2_bids.m @@ -39,18 +39,18 @@ % deal with suffixes modified by SPM % turns them into prefixes that can be handled by the default mapping if strfind(file, '_uw.mat') %#ok<*STRIFCND> - file = spm_file(file, 'prefix', 'unwarpparam_'); + file = bids.internal.file_utils(file, 'prefix', 'unwarpparam_'); file = strrep(file, '_uw.mat', '.mat'); use_suffix_as_label = true; end if strfind(file, '_seg8.mat') %#ok<*STRIFCND> - file = spm_file(file, 'prefix', 'segparam_'); + file = bids.internal.file_utils(file, 'prefix', 'segparam_'); file = strrep(file, '_seg8.mat', '.mat'); use_suffix_as_label = true; end - pth = spm_fileparts(file); - new_filename = spm_file(file, 'filename'); + pth = fileparts(file); + new_filename = bids.internal.file_utils(file, 'filename'); json = []; p = bids.internal.parse_filename(file); diff --git a/tests/test_spm_2_bids.m b/tests/test_spm_2_bids.m index e224a11..98505e0 100644 --- a/tests/test_spm_2_bids.m +++ b/tests/test_spm_2_bids.m @@ -11,8 +11,9 @@ function test_spm_2_bids_suffix() input_output = { - 'sub-01_T1w_seg8.mat', 'sub-01_label-T1w_segparam.mat' - 'sub-01_task-auditory_bold_uw.mat', 'sub-01_task-auditory_label-bold_unwarpparam.mat'}; + 'sub-01_T1w_seg8.mat', 'sub-01_label-T1w_segparam.mat'; ... + 'sub-01_task-auditory_bold_uw.mat', ... + 'sub-01_task-auditory_label-bold_unwarpparam.mat'}; for i = 1:numel(size(input_output, 1)) From 314997661b598ac52cd4c8839756ddab945a3d40 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 22:59:05 +0200 Subject: [PATCH 04/19] update CI --- .github/workflows/run_tests.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 5f474ed..edb07dd 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -30,14 +30,6 @@ jobs: submodules: true fetch-depth: 2 - - name: Install SPM - run: | - git clone https://github.com/spm/spm12.git --depth 1 - make -C spm12/src PLATFORM=octave distclean - make -C spm12/src PLATFORM=octave - make -C spm12/src PLATFORM=octave install - octave $OCTFLAGS --eval "addpath(fullfile(pwd, 'spm12')); savepath();" - - name: Install Moxunit and MOcov run: | git clone https://github.com/MOxUnit/MOxUnit.git --depth 1 @@ -48,7 +40,7 @@ jobs: - name: get bids-matlab and set up paths run: | make install_dev - octave $OCTFLAGS --eval "init_env; savepath();" + octave $OCTFLAGS --eval "init_spm_2_bids; savepath();" - name: Run tests run: | From 1bc0f756e571338f15c7e0eca337191be148099a Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 23:00:27 +0200 Subject: [PATCH 05/19] fix parameters rule --- src/utils/check_field_content.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/check_field_content.m b/src/utils/check_field_content.m index 1faa1c8..8796680 100644 --- a/src/utils/check_field_content.m +++ b/src/utils/check_field_content.m @@ -1,18 +1,18 @@ -function status = check_field_content(struct_1, struct_2) +function status = check_field_content(struct_one, struct_two) % % (C) Copyright 2021 spm_2_bids developers status = true; - if isempty(struct_2) + if isempty(struct_two) return end - if strcmp(struct_2, '*') + if strcmp(struct_two, '*') return end - shared_fields = intersect(fieldnames(struct_1), fieldnames(struct_2)); + shared_fields = intersect(fieldnames(struct_one), fieldnames(struct_two)); if isempty(shared_fields) status = false; @@ -20,7 +20,7 @@ end for i = 1:numel(shared_fields) - if ~strcmp(struct_1.(shared_fields{i}), struct_2.(shared_fields{i})) + if ~strcmp(struct_one.(shared_fields{i}), struct_two.(shared_fields{i})) status = false; return end From 78b192c88a45eb7519be5b9d2f806a0ddce138f0 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sat, 18 Sep 2021 23:27:21 +0200 Subject: [PATCH 06/19] update tests --- .gitignore | 5 +++++ run_tests.m | 4 ---- tests/test_mapping.m | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 2b533bb..152db64 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ env/ lib/bids-matlab +coverage_html +coverage.xml +test_report.log + + ## MATLAB / OCTAVE gitignore template diff --git a/run_tests.m b/run_tests.m index b458ef5..e19aa5b 100644 --- a/run_tests.m +++ b/run_tests.m @@ -1,9 +1,5 @@ % (C) Copyright 2019 spm_2_bids developers -warning('OFF'); - -spm('defaults', 'fMRI'); - folderToCover = fullfile(pwd, 'src'); testFolder = fullfile(pwd, 'tests'); diff --git a/tests/test_mapping.m b/tests/test_mapping.m index 5f25a9e..42c35ce 100644 --- a/tests/test_mapping.m +++ b/tests/test_mapping.m @@ -39,7 +39,7 @@ function test_find_mapping() map = map.default(); idx = map.find_mapping('prefix', 'rp_'); - assertEqual(find(idx), 10); + assertEqual(find(idx), 12); end From cbc81f31ac9cc723226f758f187cf161388d6cd3 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 19 Sep 2021 08:50:45 +0200 Subject: [PATCH 07/19] update test CI action --- .github/workflows/run_tests.yml | 52 ++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index edb07dd..eda23ad 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -9,9 +9,6 @@ on: pull_request: branches: '*' -env: - OCTFLAGS: --no-gui --no-window-system --silent - jobs: build: @@ -19,34 +16,41 @@ jobs: steps: - - name: Install dependencies - run: | - sudo apt-get -y -qq update - sudo apt-get -y install octave liboctave-dev - - name: Clone spm_2_bids uses: actions/checkout@v2 with: submodules: true - fetch-depth: 2 - - - name: Install Moxunit and MOcov - run: | - git clone https://github.com/MOxUnit/MOxUnit.git --depth 1 - make -C MOxUnit install - git clone https://github.com/MOcov/MOcov.git --depth 1 - make -C MOcov install + fetch-depth: 2 - - name: get bids-matlab and set up paths + - name: get bids-matlab run: | make install_dev - octave $OCTFLAGS --eval "init_spm_2_bids; savepath();" - - - name: Run tests - run: | - octave $OCTFLAGS --eval "run_tests" - cat test_report.log | grep 0 - bash <(curl -s https://codecov.io/bash) + + - name: MOxUnit Action + uses: joergbrech/moxunit-action@master + with: + tests: tests # files or directories containing the MOxUnit test cases + src: src lib # directories to be added to the Octave search path before running the tests. + ext: tests/utils # External resources to add to the search put (excluded from coverage) + # data: # Directory for test data + with_coverage: true + cover_xml_file: coverage.xml + + - name: Upload coverage + uses: actions/upload-artifact@v1 + with: + name: coverage_file + path: coverage.xml + + - name: Code coverage + uses: codecov/codecov-action@v1 + with: + file: coverage.xml # optional + flags: unittests # optional + name: codecov-umbrella # optional + fail_ci_if_error: true # optional (default = false) + + From 0342d647a0ed144455a05983f85ba2104600457b Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 19 Sep 2021 09:26:54 +0200 Subject: [PATCH 08/19] update Github action --- .github/workflows/run_tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index eda23ad..1cb0196 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -22,7 +22,7 @@ jobs: submodules: true fetch-depth: 2 - - name: get bids-matlab + - name: get bids-matlab and set up paths run: | make install_dev @@ -30,7 +30,7 @@ jobs: uses: joergbrech/moxunit-action@master with: tests: tests # files or directories containing the MOxUnit test cases - src: src lib # directories to be added to the Octave search path before running the tests. + src: src lib/bids-matlab # directories to be added to the Octave search path before running the tests. ext: tests/utils # External resources to add to the search put (excluded from coverage) # data: # Directory for test data with_coverage: true From 68ded520390eaa0d73a2da4afeb970798c0ffd45 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 19 Sep 2021 09:58:29 +0200 Subject: [PATCH 09/19] update notebooks --- {examples => notebooks}/.gitignore | 0 {examples => notebooks}/demo.ipynb | 214 ++++++++++++++++++----------- 2 files changed, 131 insertions(+), 83 deletions(-) rename {examples => notebooks}/.gitignore (100%) rename {examples => notebooks}/demo.ipynb (79%) diff --git a/examples/.gitignore b/notebooks/.gitignore similarity index 100% rename from examples/.gitignore rename to notebooks/.gitignore diff --git a/examples/demo.ipynb b/notebooks/demo.ipynb similarity index 79% rename from examples/demo.ipynb rename to notebooks/demo.ipynb index c23a573..93535f4 100644 --- a/examples/demo.ipynb +++ b/notebooks/demo.ipynb @@ -2,84 +2,87 @@ "cells": [ { "cell_type": "markdown", - "id": "a4c07e0c-8673-4fa8-bc31-800409fb09c4", - "metadata": {}, "source": [ "# SPM_2_BIDS DEMO\n", "\n", - "**Helping you convert your SPM output into a BIDS compliant datasets.**\n" - ] + "**Helping you convert your SPM output into a BIDS compliant datasets.**\n", + "\n", + "## BIDS filenames\n", + "\n", + "Ideally we would like to have the same pipeline for statistical analysis \n", + "whether our data was preprocessed with SPM or with fmriprep (for example).\n", + "\n", + "This is possible under the condition that the input files for the statistical analysis are BIDS compliant: \n", + "meaning that they follow the typical pattern of BIDS files:\n", + "\n", + "- pseudo \"regular expression\" : `entity-label(_entity-label)+_suffix.extension`\n", + "\n", + "\n", + "- `entity`, `label`, `suffix`, `extension` are alphanumeric only (no special character): `([a-zA-Z0-9])+`\n", + " - suffixes can be: `T1w` or `bold` but not `T1w_skullstripped` (no underscore allowed)\n", + "\n", + "\n", + "- entity and label are separated by a dash: \n", + " `entity-label --> ([a-zA-Z0-9])+-([a-zA-Z0-9])+`\n", + " - you can have: `sub-01` but not `sub-01-blind`\n", + " \n", + "\n", + "\n", + "- entity-label pairs are separated by an underscore:\n", + " `entity-label(_entity-label)+ --> ([a-zA-Z0-9])+-([a-zA-Z0-9])+(_([a-zA-Z0-9])+-([a-zA-Z0-9])+)+`\n", + "\n", + "\n", + "- **prefixes are not a thing in official BIDS names**\n", + "\n", + "BIDS has a number of [officially recognised entities](https://bids-specification.readthedocs.io/en/stable/99-appendices/04-entity-table.html) (`sub`, `ses`, `task`...) \n", + "that must come in a specific order for each data type.\n", + "\n", + "BIDS derivatives adds a few more entities (`desc`, `space`, `res`...) \n", + "and suffixes (`pseg`, `dseg`, `mask`...) \n", + "that can be used to name and describe preprocessed data.\n", + "\n", + "## Typical SPM filenames\n", + "\n", + "SPM typically adds prefixes to filenames and concatenates them.\n", + "\n", + "- `r` for realigned or resliced\n", + "- `w` for warped (often means normalized in MNI space)\n", + "- `a` for slice time corrected images\n", + "- `u` for unwarped\n", + "- `s` for smoothed\n", + "- `c1` for grey matter tissue probability maps\n", + "- ...\n", + "\n", + "## SPM to BIDS\n", + "\n", + "spm_2_bids offers a default mapping to rename the output of raw BIDS datasets preprocessed with SPM12\n", + "into BIDS compliant derivatives datasets, by suggesting a name for each file by removing prefixes and \n", + "adding the appropriate entities to be added.\n", + "\n", + "Files are not actually renamed by spm_2_bids (yet).\n" + ], + "metadata": {} }, { "cell_type": "code", "execution_count": 2, - "id": "68482373-0288-4920-99a6-68e7db8bac44", - "metadata": {}, + "source": [ + "run ../init_spm_2_bids.m" + ], "outputs": [ { - "name": "stdout", "output_type": "stream", + "name": "stdout", "text": [ "Correct matlab/octave verions and added to the path!\n" ] } ], - "source": [ - "run ../init_spm_2_bids.m" - ] + "metadata": {} }, { "cell_type": "code", "execution_count": 13, - "id": "0d1179df-bfa6-494c-a900-ab667d6bfa5d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "sub-01_T1w_seg8.mat\t-->\tsub-01_label-T1w_segparam.mat\n", - "sub-01_task-auditory_bold_uw.mat\t-->\tsub-01_task-auditory_label-bold_unwarpparam.mat\n", - "y_sub-01_T1w.nii\t-->\tsub-01_from-T1w_to-IXI549Space_mode-image_xfm.nii\n", - "iy_sub-01_T1w.nii\t-->\tsub-01_from-IXI549Space_to-T1w_mode-image_xfm.nii\n", - "y_sub-01_T2w.nii\t-->\tsub-01_from-T2w_to-IXI549Space_mode-image_xfm.nii\n", - "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", - "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "c1sub-01_T1w.nii\t-->\tsub-01_space-individual_label-GM_probseg.nii\n", - "c2sub-01_T1w.nii\t-->\tsub-01_space-individual_label-WM_probseg.nii\n", - "c3sub-01_T1w.nii\t-->\tsub-01_space-individual_label-CSF_probseg.nii\n", - "msub-01_T1w.nii\t-->\tsub-01_space-individual_desc-biascor_T1w.nii\n", - "wmsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", - "wsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", - "wc1sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-GM_probseg.nii\n", - "wc2sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-WM_probseg.nii\n", - "wc3sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-CSF_probseg.nii\n", - "asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-stc_bold.nii\n", - "usub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii\n", - "rp_sub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", - "rp_asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", - "meansub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", - "meanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", - "meanuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", - "wsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", - "wuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", - "wusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", - "wrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", - "wrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", - "wmeanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-mean_bold.nii\n", - "swsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "swusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "swrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "swrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", - "ssub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", - "suasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", - "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", - "srsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", - "srasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n" - ] - } - ], "source": [ "input_files = { 'sub-01_T1w_seg8.mat'; ...\n", " 'sub-01_task-auditory_bold_uw.mat'; ...\n", @@ -130,22 +133,66 @@ " fprintf(1, '%s\\t-->\\t%s\\n', input_files{i, 1}, filename);\n", "\n", "end" - ] + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "sub-01_T1w_seg8.mat\t-->\tsub-01_label-T1w_segparam.mat\n", + "sub-01_task-auditory_bold_uw.mat\t-->\tsub-01_task-auditory_label-bold_unwarpparam.mat\n", + "y_sub-01_T1w.nii\t-->\tsub-01_from-T1w_to-IXI549Space_mode-image_xfm.nii\n", + "iy_sub-01_T1w.nii\t-->\tsub-01_from-IXI549Space_to-T1w_mode-image_xfm.nii\n", + "y_sub-01_T2w.nii\t-->\tsub-01_from-T2w_to-IXI549Space_mode-image_xfm.nii\n", + "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "c1sub-01_T1w.nii\t-->\tsub-01_space-individual_label-GM_probseg.nii\n", + "c2sub-01_T1w.nii\t-->\tsub-01_space-individual_label-WM_probseg.nii\n", + "c3sub-01_T1w.nii\t-->\tsub-01_space-individual_label-CSF_probseg.nii\n", + "msub-01_T1w.nii\t-->\tsub-01_space-individual_desc-biascor_T1w.nii\n", + "wmsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", + "wsub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n", + "wc1sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-GM_probseg.nii\n", + "wc2sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-WM_probseg.nii\n", + "wc3sub-01_T1w.nii\t-->\tsub-01_space-IXI549Space_label-CSF_probseg.nii\n", + "asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-stc_bold.nii\n", + "usub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-realignUnwarp_bold.nii\n", + "rp_sub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", + "rp_asub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_desc-confounds_regressors.tsv\n", + "meansub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "meanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "meanuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-mean_bold.nii\n", + "wsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-preproc_bold.nii\n", + "wmeanusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-mean_bold.nii\n", + "swsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swuasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swusub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swrsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "swrasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-IXI549Space_desc-smth_bold.nii\n", + "ssub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "suasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "susub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "srsub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n", + "srasub-01_task-auditory_bold.nii\t-->\tsub-01_task-auditory_space-individual_desc-smth_bold.nii\n" + ] + } + ], + "metadata": {} }, { "cell_type": "markdown", - "id": "cdb56e9a-3757-45a6-ba5a-c1228f478a3e", - "metadata": {}, "source": [ "# Override the default name map" - ] + ], + "metadata": {} }, { "cell_type": "code", "execution_count": 20, - "id": "547873ea-d673-4338-998e-a10ea80b1682", - "metadata": {}, - "outputs": [], "source": [ "map = Mapping();\n", "\n", @@ -169,25 +216,13 @@ " 'name_spec', name_spec);\n", "\n", "map = map.flatten_mapping();\n" - ] + ], + "outputs": [], + "metadata": {} }, { "cell_type": "code", "execution_count": 21, - "id": "6dde6430-e419-4771-8a61-1b5ba6d362d6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "c1sub-01_T1w.surf.gii\t-->\tsub-01_desc-pialsurf_T1w.gii\n", - "wmsub-01_desc-skullstripped_T1w.nii\t-->\tsub-01_space-IXI549Space_res-1pt0_desc-preproc_T1w.nii\n", - "wmsub-01_desc-skullstripped_T2w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T2w.nii\n", - "wmsub-01_desc-preproc_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n" - ] - } - ], "source": [ "input_output = {'c1sub-01_T1w.surf.gii'; ... % new mapping for surface data\n", " 'wmsub-01_desc-skullstripped_T1w.nii'; ... % new mapping for skulltripped data\n", @@ -202,7 +237,20 @@ " fprintf(1, '%s\\t-->\\t%s\\n', input_output{i, 1}, filename);\n", "\n", "end" - ] + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "c1sub-01_T1w.surf.gii\t-->\tsub-01_desc-pialsurf_T1w.gii\n", + "wmsub-01_desc-skullstripped_T1w.nii\t-->\tsub-01_space-IXI549Space_res-1pt0_desc-preproc_T1w.nii\n", + "wmsub-01_desc-skullstripped_T2w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T2w.nii\n", + "wmsub-01_desc-preproc_T1w.nii\t-->\tsub-01_space-IXI549Space_desc-preproc_T1w.nii\n" + ] + } + ], + "metadata": {} } ], "metadata": { @@ -234,4 +282,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file From 3ae346e28ff5dbbabfa7e14def1b61fca85feb2f Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 19 Sep 2021 10:00:38 +0200 Subject: [PATCH 10/19] update test github action --- .github/workflows/run_tests.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 1cb0196..9c2ebc4 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -21,6 +21,13 @@ jobs: with: submodules: true fetch-depth: 2 + + - name: Install JSONio + run: | + git clone git://github.com/gllmflndn/JSONio.git --depth 1 + cd JSONio + mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS + cd .. - name: get bids-matlab and set up paths run: | From db4ca09ab64332b39d47554930594ecd7644536e Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Sun, 19 Sep 2021 10:18:47 +0200 Subject: [PATCH 11/19] update github action --- .github/workflows/run_tests.yml | 22 ++++++++++------------ .gitignore | 3 +-- Makefile | 10 +++++++++- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 9c2ebc4..e478520 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -6,38 +6,36 @@ on: - master - main - dev + pull_request: branches: '*' jobs: build: - runs-on: ubuntu-20.04 steps: + - name: Install dependencies + run: | + sudo apt-get -y -qq update + sudo apt-get -y install octave liboctave-dev + - name: Clone spm_2_bids uses: actions/checkout@v2 with: submodules: true - fetch-depth: 2 - - - name: Install JSONio - run: | - git clone git://github.com/gllmflndn/JSONio.git --depth 1 - cd JSONio - mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS - cd .. + fetch-depth: 2 - - name: get bids-matlab and set up paths + - name: get bids-matlab and JSONio run: | - make install_dev + make install_dev_octave - name: MOxUnit Action uses: joergbrech/moxunit-action@master with: tests: tests # files or directories containing the MOxUnit test cases - src: src lib/bids-matlab # directories to be added to the Octave search path before running the tests. + src: src lib/bids-matlab lib/JSONio # directories to be added to path before running the tests. ext: tests/utils # External resources to add to the search put (excluded from coverage) # data: # Directory for test data with_coverage: true diff --git a/.gitignore b/.gitignore index 152db64..d278820 100644 --- a/.gitignore +++ b/.gitignore @@ -6,13 +6,12 @@ env/ lib/bids-matlab +lib/JSONio coverage_html coverage.xml test_report.log - - ## MATLAB / OCTAVE gitignore template # From : https://github.com/github/gitignore/blob/master/Global/MATLAB.gitignore diff --git a/Makefile b/Makefile index 4db37b9..d2b148b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ install_dev: git clone https://github.com/bids-standard/bids-matlab.git lib/bids-matlab cd lib/bids-matlab && git checkout dev + git clone git://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio + +install_dev_octave: + git clone https://github.com/bids-standard/bids-matlab.git lib/bids-matlab + cd lib/bids-matlab && git checkout dev + git clone git://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio + cd lib/JSONio && mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS clean: - rm -rf lib/bids-matlab \ No newline at end of file + rm -rf lib/bids-matlab + rm -rf lib/JSONio \ No newline at end of file From 06de48beb16ba7e2d827c0f99ff7a5beb144c396 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 1 Nov 2021 19:41:08 +0100 Subject: [PATCH 12/19] use bids.File --- src/spm_2_bids.m | 10 ++++++++-- tests/test_spm_2_bids.m | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/spm_2_bids.m b/src/spm_2_bids.m index 0d28c85..ba35d5d 100644 --- a/src/spm_2_bids.m +++ b/src/spm_2_bids.m @@ -136,12 +136,18 @@ overwrite = true; spec.prefix = ''; - spec.use_schema = false; + use_schema = false; p = set_missing_fields(p, spec, overwrite); p = reorder_entities(p, cfg); - [new_filename, pth, json] = bids.create_filename(p, file); + bidsFile = bids.File(file, use_schema, p); + bidsFile = bidsFile.reorder_entities(p.entity_order); + bidsFile = bidsFile.create_filename; + + new_filename = bidsFile.filename; + pth = bidsFile.pth; + json = bids.derivatives_json(new_filename); % TODO update json content p = bids.internal.parse_filename(file); diff --git a/tests/test_spm_2_bids.m b/tests/test_spm_2_bids.m index 98505e0..82ee2ac 100644 --- a/tests/test_spm_2_bids.m +++ b/tests/test_spm_2_bids.m @@ -8,10 +8,19 @@ initTestSuite; end +function test_spm_2_bids_order_entities() + + file = 'wmsub-01_desc-skullstripped_T1w.nii'; + new_filename = spm_2_bids(file); + assertEqual(new_filename, 'sub-01_space-IXI549Space_desc-preproc_T1w.nii'); + +end + function test_spm_2_bids_suffix() input_output = { - 'sub-01_T1w_seg8.mat', 'sub-01_label-T1w_segparam.mat'; ... + 'sub-01_T1w_seg8.mat', ... + 'sub-01_label-T1w_segparam.mat' 'sub-01_task-auditory_bold_uw.mat', ... 'sub-01_task-auditory_label-bold_unwarpparam.mat'}; @@ -73,14 +82,6 @@ function test_spm_2_bids_new_mapping() end -function test_spm_2_bids_order_entities() - - file = 'wmsub-01_desc-skullstripped_T1w.nii'; - new_filename = spm_2_bids(file); - assertEqual(new_filename, 'sub-01_space-IXI549Space_desc-preproc_T1w.nii'); - -end - function test_spm_2_bids_no_prefix() file = 'sub-01_ses-02_T1w.nii'; From 91136a22fe667414b1dec9128ecf4a10d52c7d76 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 10:21:04 +0100 Subject: [PATCH 13/19] adapt to new bids.File function and refactor --- miss_hit.cfg | 2 +- src/spm_2_bids.m | 116 +++++++++++++++++++++++++++-------------------- 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/miss_hit.cfg b/miss_hit.cfg index 78ada53..1ea82bf 100644 --- a/miss_hit.cfg +++ b/miss_hit.cfg @@ -17,5 +17,5 @@ copyright_entity: "spm_2_bids developers" # metric for code quality metric "cnest": limit 5 metric "file_length": limit 500 -metric "cyc": limit 15 +metric "cyc": limit 13 metric "parameters": limit 5 \ No newline at end of file diff --git a/src/spm_2_bids.m b/src/spm_2_bids.m index ba35d5d..a3b435a 100644 --- a/src/spm_2_bids.m +++ b/src/spm_2_bids.m @@ -34,29 +34,23 @@ mapping = map.mapping; cfg = map.cfg; - use_suffix_as_label = false; - % deal with suffixes modified by SPM % turns them into prefixes that can be handled by the default mapping - if strfind(file, '_uw.mat') %#ok<*STRIFCND> - file = bids.internal.file_utils(file, 'prefix', 'unwarpparam_'); - file = strrep(file, '_uw.mat', '.mat'); - use_suffix_as_label = true; - end - if strfind(file, '_seg8.mat') %#ok<*STRIFCND> - file = bids.internal.file_utils(file, 'prefix', 'segparam_'); - file = strrep(file, '_seg8.mat', '.mat'); + use_suffix_as_label = false; + [file, status(1)] = turn_spm_suffix_in_prefix(file, '_uw.mat', 'unwarpparam_'); + [file, status(2)] = turn_spm_suffix_in_prefix(file, '_seg8.mat', 'segparam_'); + if any(status) use_suffix_as_label = true; end - pth = fileparts(file); - new_filename = bids.internal.file_utils(file, 'filename'); - json = []; + bf = bids.File(file, 'use_schema', false); + pth = bf.bids_path; + new_filename = bf.filename; - p = bids.internal.parse_filename(file); + json = []; % TO DO allow renaming even if there is no prefix ? - if isempty(p.prefix) + if isempty(bf.prefix) return end @@ -66,7 +60,7 @@ % the right mapping % look for the right prefix in the mapping - prefix_match = map.find_mapping('prefix', p.prefix); + prefix_match = map.find_mapping('prefix', bf.prefix); % TODO implement methods in Mapping to filter by suffix / extention / % entities @@ -75,12 +69,12 @@ % if none is mentioned anywhere in the mapping then anything goes suffix_match = true(size(mapping)); if ~all(cellfun('isempty', {mapping.suffix}')) - suffix_match = any([strcmp({mapping.suffix}', p.suffix), ... + suffix_match = any([strcmp({mapping.suffix}', bf.suffix), ... strcmp({mapping.suffix}', '*')], 2); end ext_match = true(size(mapping)); if ~all(cellfun('isempty', {mapping.ext}')) - ext_match = any([strcmp({mapping.ext}', p.ext), ... + ext_match = any([strcmp({mapping.ext}', bf.extension), ... strcmp({mapping.ext}', '*')], 2); end @@ -96,7 +90,7 @@ idx = find(needs_entity_check); for i = 1:numel(idx) - status = check_field_content(p.entities, mapping(idx(i)).entities); + status = check_field_content(bf.entities, mapping(idx(i)).entities); entitiy_match(idx(i)) = status; end end @@ -119,66 +113,78 @@ if isempty(spec) % TODO this warning should probably go in the find_mapping methods - msg = sprintf('Unknown prefix: %s', p.prefix); + msg = sprintf('Unknown prefix: %s', bf.prefix); warning('spm_2_bids:unknownPrefix', msg); %#ok return end spec = add_fwhm_to_smooth_label(spec, cfg); - spec = adapt_from_label_to_input(spec, p); + spec = adapt_from_label_to_input(spec, bf); if use_suffix_as_label - spec.entities.label = p.suffix; + spec.entities.label = bf.suffix; end spec = use_config_spec(spec, cfg); - overwrite = true; - spec.prefix = ''; - use_schema = false; - p = set_missing_fields(p, spec, overwrite); + bf = update_filename(bf, spec, cfg); + + % arg out + pth = bf.bids_path; + + new_filename = bf.filename; - p = reorder_entities(p, cfg); + json = bids.derivatives_json(bf.filename); + json.content.RawSources{1} = strrep(bf.filename, bf.prefix, ''); - bidsFile = bids.File(file, use_schema, p); - bidsFile = bidsFile.reorder_entities(p.entity_order); - bidsFile = bidsFile.create_filename; +end + +function bf = update_filename(bf, spec, cfg) - new_filename = bidsFile.filename; - pth = bidsFile.pth; - json = bids.derivatives_json(new_filename); + bf.prefix = ''; + if isfield(spec, 'suffix') + bf.suffix = spec.suffix; + end + if isfield(spec, 'ext') + bf.extension = spec.ext; + end + if isfield(spec, 'entities') + entities = fieldnames(spec.entities); + for i = 1:numel(entities) + bf = bf.set_entity(entities{i}, spec.entities.(entities{i})); + end + end - % TODO update json content - p = bids.internal.parse_filename(file); - json.content.RawSources{1} = strrep(p.filename, p.prefix, ''); + bf = reorder_entities(bf, cfg); + bf = bf.update; end -function spec = add_fwhm_to_smooth_label(spec, cfg) +function bf = add_fwhm_to_smooth_label(bf, cfg) % % adds the FWHM to the description label for smoothing % - if isfield(spec, 'entities') && ... - isfield(spec.entities, 'desc') && ... - strcmp(spec.entities.desc, 'smth') && ... + if isfield(bf, 'entities') && ... + isfield(bf.entities, 'desc') && ... + strcmp(bf.entities.desc, 'smth') && ... ~isempty(cfg.fwhm) - spec.entities.desc = sprintf('smth%i', cfg.fwhm); + bf.entities.desc = sprintf('smth%i', cfg.fwhm); end end -function spec = adapt_from_label_to_input(spec, p) +function spec = adapt_from_label_to_input(spec, bf) % % for deformation fields % - if strcmp(p.prefix, 'y_') - spec.entities.from = p.suffix; + if strcmp(bf.prefix, 'y_') + spec.entities.from = bf.suffix; spec.entities = orderfields(spec.entities, {'from', 'to', 'mode'}); - elseif strcmp(p.prefix, 'iy_') - spec.entities.to = p.suffix; + elseif strcmp(bf.prefix, 'iy_') + spec.entities.to = bf.suffix; spec.entities = orderfields(spec.entities, {'from', 'to', 'mode'}); end @@ -204,14 +210,14 @@ end -function p = reorder_entities(p, cfg) +function bf = reorder_entities(bf, cfg) % % put entity from raw bids before those of derivatives % and make sure that derivatives entities are in the right order % % - entities = fieldnames(p.entities); + entities = fieldnames(bf.entities); is_raw_entity = ~ismember(entities, cfg.entity_order); @@ -221,6 +227,18 @@ entities(~is_raw_entity)); derivative_entities = cfg.entity_order(derivative_entities_present); - p.entity_order = cat(1, raw_entities, derivative_entities); + bf = bf.reorder_entities(cat(1, raw_entities, derivative_entities)); + +end +function [filename, status] = turn_spm_suffix_in_prefix(filename, pattern, string) + status = false; + + if strfind(filename, pattern) %#ok<*STRIFCND> + filename = bids.internal.file_utils(filename, 'prefix', string); + filename = strrep(filename, ... + pattern, ... + ['.' bids.internal.file_utils(filename, 'ext')]); + status = true; + end end From fa4788cc5cc4c0283f5ec112e5d58acb0dbea830 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 10:33:56 +0100 Subject: [PATCH 14/19] run precommit --- .github/workflows/miss_hit_code_quality.yml | 4 +-- .github/workflows/miss_hit_code_style.yml | 4 +-- .github/workflows/run_tests.yml | 27 +++++++++------------ .gitignore | 2 -- .pre-commit-config.yaml | 16 +++++++++++- Makefile | 2 +- README.md | 2 +- binder/postBuild | 1 - docs/.gitignore | 2 +- docs/requirements.txt | 2 +- docs/source/conf.py | 4 +-- docs/source/index.rst | 2 +- lib/README.md | 2 -- miss_hit.cfg | 4 +-- notebooks/.gitignore | 2 +- notebooks/demo.ipynb | 2 +- requirements.txt | 2 +- src/README.md | 2 +- version.txt | 2 +- 19 files changed, 44 insertions(+), 40 deletions(-) diff --git a/.github/workflows/miss_hit_code_quality.yml b/.github/workflows/miss_hit_code_quality.yml index 78c6117..faa0b44 100644 --- a/.github/workflows/miss_hit_code_quality.yml +++ b/.github/workflows/miss_hit_code_quality.yml @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip3 install -r requirements.txt + pip3 install -r requirements.txt - name: MISS_HIT Metrics run: | @@ -40,4 +40,4 @@ jobs: - name: MISS_HIT Bug finder run: | - mh_lint \ No newline at end of file + mh_lint diff --git a/.github/workflows/miss_hit_code_style.yml b/.github/workflows/miss_hit_code_style.yml index eaef1ef..ea44532 100644 --- a/.github/workflows/miss_hit_code_style.yml +++ b/.github/workflows/miss_hit_code_style.yml @@ -32,8 +32,8 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip3 install -r requirements.txt + pip3 install -r requirements.txt - name: MISS_HIT Code style run: | - mh_style --process-slx \ No newline at end of file + mh_style --process-slx diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index e478520..68c9225 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -19,14 +19,14 @@ jobs: - name: Install dependencies run: | sudo apt-get -y -qq update - sudo apt-get -y install octave liboctave-dev + sudo apt-get -y install octave liboctave-dev - - name: Clone spm_2_bids + - name: Clone spm_2_bids uses: actions/checkout@v2 with: submodules: true - fetch-depth: 2 - + fetch-depth: 2 + - name: get bids-matlab and JSONio run: | make install_dev_octave @@ -35,17 +35,17 @@ jobs: uses: joergbrech/moxunit-action@master with: tests: tests # files or directories containing the MOxUnit test cases - src: src lib/bids-matlab lib/JSONio # directories to be added to path before running the tests. + src: src lib/bids-matlab lib/JSONio # directories to be added to path before running the tests. ext: tests/utils # External resources to add to the search put (excluded from coverage) - # data: # Directory for test data + # data: # Directory for test data with_coverage: true cover_xml_file: coverage.xml - name: Upload coverage - uses: actions/upload-artifact@v1 - with: - name: coverage_file - path: coverage.xml + uses: actions/upload-artifact@v1 + with: + name: coverage_file + path: coverage.xml - name: Code coverage uses: codecov/codecov-action@v1 @@ -53,9 +53,4 @@ jobs: file: coverage.xml # optional flags: unittests # optional name: codecov-umbrella # optional - fail_ci_if_error: true # optional (default = false) - - - - - + fail_ci_if_error: true # optional (default = false) diff --git a/.gitignore b/.gitignore index d278820..b35d9b8 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,3 @@ codegen/ # Octave session info octave-workspace - - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a2858fb..310aa22 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,4 +25,18 @@ repos: entry: mh_lint files: ^(.*\.(m|slx))$ language: python - additional_dependencies: [miss_hit] \ No newline at end of file + additional_dependencies: [miss_hit] + +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + +- repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.9.0 + hooks: + - id: rst-backticks # Detect common mistake of using single backticks when writing rst + - id: rst-inline-touching-normal # Detect mistake of inline code touching normal text in rst diff --git a/Makefile b/Makefile index d2b148b..fa212e8 100644 --- a/Makefile +++ b/Makefile @@ -11,4 +11,4 @@ install_dev_octave: clean: rm -rf lib/bids-matlab - rm -rf lib/JSONio \ No newline at end of file + rm -rf lib/JSONio diff --git a/README.md b/README.md index 0f01f9f..4a4d073 100644 --- a/README.md +++ b/README.md @@ -26,4 +26,4 @@ Most of the renaming is based on the SPM prefixes combinations. It is configurable to adapt to new set of prefixes. - [Dependencies](./lib/README.md) -- [Documentation](https://spm-2-bids.readthedocs.io/en/latest/) \ No newline at end of file +- [Documentation](https://spm-2-bids.readthedocs.io/en/latest/) diff --git a/binder/postBuild b/binder/postBuild index 7e769e8..26dfe78 100644 --- a/binder/postBuild +++ b/binder/postBuild @@ -9,4 +9,3 @@ cd JSONio; mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS; cd .. octave --no-gui --no-window-system --silent --eval "addpath (fullfile (getenv (\"HOME\"), \"JSONio\")); savepath ();" cd ${HOME}/examples - diff --git a/docs/.gitignore b/docs/.gitignore index c795b05..378eac2 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1 @@ -build \ No newline at end of file +build diff --git a/docs/requirements.txt b/docs/requirements.txt index a4b9ccc..8d7a63f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ Sphinx sphinxcontrib-matlabdomain sphinxcontrib-napoleon -sphinx_rtd_theme \ No newline at end of file +sphinx_rtd_theme diff --git a/docs/source/conf.py b/docs/source/conf.py index b4c2ccd..2d89d7a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -30,7 +30,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinxcontrib.matlab', + 'sphinxcontrib.matlab', 'sphinx.ext.autodoc'] matlab_src_dir = os.path.dirname(os.path.abspath('../../src')) primary_domain = 'mat' @@ -83,4 +83,4 @@ 'searchbox.html', 'donate.html', ] -} \ No newline at end of file +} diff --git a/docs/source/index.rst b/docs/source/index.rst index 7170e79..aff256a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,7 +12,7 @@ Welcome to spm_2_bids documentation! ``spm_2_bids`` only provides names to use but does not actually rename the files. .. automodule:: src - + .. autofunction:: spm_2_bids .. automodule:: src.defaults diff --git a/lib/README.md b/lib/README.md index e8b8685..3453b8a 100644 --- a/lib/README.md +++ b/lib/README.md @@ -7,5 +7,3 @@ This code requires: - [BIDS-matlab](https://github.com/bids-standard/bids-matlab) from commi [b7732b0cb](https://github.com/bids-standard/bids-matlab/commit/b7732b0cb2103ee0cfa095ee604bee4086844cad) or later. In doubt use the `dev` branch of bids-matlab. - - diff --git a/miss_hit.cfg b/miss_hit.cfg index 1ea82bf..f4b0e98 100644 --- a/miss_hit.cfg +++ b/miss_hit.cfg @@ -7,7 +7,7 @@ regex_function_name: "[a-z]+(_[a-z0-9]+)*" regex_class_name: "[A-Z]{1}[a-z]+" regex_script_name: "[a-z]+(_[a-z]+)*" -# suppress_rule: "naming_parameters" +# suppress_rule: "naming_parameters" # regex_parameter_name: "[a-z]+(_[a-z0-9]+)*" exclude_dir: "lib" @@ -18,4 +18,4 @@ copyright_entity: "spm_2_bids developers" metric "cnest": limit 5 metric "file_length": limit 500 metric "cyc": limit 13 -metric "parameters": limit 5 \ No newline at end of file +metric "parameters": limit 5 diff --git a/notebooks/.gitignore b/notebooks/.gitignore index 58461f2..763513e 100644 --- a/notebooks/.gitignore +++ b/notebooks/.gitignore @@ -1 +1 @@ -.ipynb_checkpoints \ No newline at end of file +.ipynb_checkpoints diff --git a/notebooks/demo.ipynb b/notebooks/demo.ipynb index 93535f4..dc1b658 100644 --- a/notebooks/demo.ipynb +++ b/notebooks/demo.ipynb @@ -282,4 +282,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +} diff --git a/requirements.txt b/requirements.txt index 0723c45..84a24f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ pre-commit jupyterlab octave_kernel jinja2 --r docs/requirements.txt \ No newline at end of file +-r docs/requirements.txt diff --git a/src/README.md b/src/README.md index e413cd5..27cbbff 100644 --- a/src/README.md +++ b/src/README.md @@ -1,3 +1,3 @@ # Source code -# Main functions \ No newline at end of file +# Main functions diff --git a/version.txt b/version.txt index 9ff151c..b82608c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.1.0 \ No newline at end of file +v0.1.0 From e3c8f8931bd5ad9d16bddfba56b03ef6cbabd228 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 10:39:12 +0100 Subject: [PATCH 15/19] update test CI --- .github/workflows/run_tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 68c9225..812c6a0 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -8,7 +8,7 @@ on: - dev pull_request: - branches: '*' + branches: ['*'] jobs: build: @@ -32,7 +32,7 @@ jobs: make install_dev_octave - name: MOxUnit Action - uses: joergbrech/moxunit-action@master + uses: joergbrech/moxunit-action@v1.2.0 with: tests: tests # files or directories containing the MOxUnit test cases src: src lib/bids-matlab lib/JSONio # directories to be added to path before running the tests. From 1a8e842066d86e86c972a8e49245758ee5f1cf99 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 10:48:56 +0100 Subject: [PATCH 16/19] update CI --- .github/workflows/run_tests.yml | 4 ++-- Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 812c6a0..596a22c 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -35,8 +35,8 @@ jobs: uses: joergbrech/moxunit-action@v1.2.0 with: tests: tests # files or directories containing the MOxUnit test cases - src: src lib/bids-matlab lib/JSONio # directories to be added to path before running the tests. - ext: tests/utils # External resources to add to the search put (excluded from coverage) + src: src # directories to be added to path before running the tests. + ext: tests/utils lib/bids-matlab lib/JSONio # External resources to add to the search put (excluded from coverage) # data: # Directory for test data with_coverage: true cover_xml_file: coverage.xml diff --git a/Makefile b/Makefile index fa212e8..a252fd6 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ install_dev: git clone https://github.com/bids-standard/bids-matlab.git lib/bids-matlab cd lib/bids-matlab && git checkout dev - git clone git://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio + git clone https://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio install_dev_octave: git clone https://github.com/bids-standard/bids-matlab.git lib/bids-matlab cd lib/bids-matlab && git checkout dev - git clone git://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio + git clone https://github.com/gllmflndn/JSONio.git --depth 1 lib/JSONio cd lib/JSONio && mkoctfile --mex jsonread.c jsmn.c -DJSMN_PARENT_LINKS clean: From 2c474cf3b3a083a254c109af798d713409bebe43 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 11:54:24 +0100 Subject: [PATCH 17/19] fix tests octave --- README.md | 1 + init_spm_2_bids.m | 2 ++ lib/README.md | 4 +--- src/defaults/Mapping.m | 28 +++++++++++++--------------- tests/test_spm_2_bids.m | 4 ++++ 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4a4d073..dc10cd0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ When you have set up your repo [![Build Status](https://travis-ci.com/Remi-gau/template_matlab_analysis.svg?branch=master)](https://travis-ci.com/Remi-gau/template_matlab_analysis) --> + # spm_2_bids Small code base to help convert the MRI spm output to a valid bids derivatives. diff --git a/init_spm_2_bids.m b/init_spm_2_bids.m index acf5564..9859dd3 100644 --- a/init_spm_2_bids.m +++ b/init_spm_2_bids.m @@ -22,6 +22,8 @@ if is_octave + more off; + % Exit if min version is not satisfied if ~compare_versions(OCTAVE_VERSION, OCTAVE_VER, '>=') error('Minimum required Octave version: %s', OCTAVE_VER); diff --git a/lib/README.md b/lib/README.md index 3453b8a..e1aa869 100644 --- a/lib/README.md +++ b/lib/README.md @@ -4,6 +4,4 @@ This code requires: - SPM12 for some actions ??? -- [BIDS-matlab](https://github.com/bids-standard/bids-matlab) from commi - [b7732b0cb](https://github.com/bids-standard/bids-matlab/commit/b7732b0cb2103ee0cfa095ee604bee4086844cad) - or later. In doubt use the `dev` branch of bids-matlab. +- [BIDS-matlab](https://github.com/bids-standard/bids-matlab) ; version 0.1.0 diff --git a/src/defaults/Mapping.m b/src/defaults/Mapping.m index b0259a3..89c1a56 100644 --- a/src/defaults/Mapping.m +++ b/src/defaults/Mapping.m @@ -164,31 +164,30 @@ % map = map.default; % - prfx_spec = { ... - { obj.bias_cor }, obj.cfg.segment.bias_corrected; ... + prfx_spec = {{ obj.bias_cor }, obj.cfg.segment.bias_corrected; ... { 'c1' }, obj.cfg.segment.gm; ... { 'c2' }, obj.cfg.segment.wm; ... { 'c3' }, obj.cfg.segment.csf; ... { 'iy_' }, obj.cfg.segment.deformation_field.from_mni; ... { 'y_' }, obj.cfg.segment.deformation_field.to_mni; ... - { 'segparam_' }, obj.cfg.segment.param; ... - { obj.stc, [obj.unwarp, obj.stc]}, obj.cfg.stc; ... - { 'unwarpparam_' }, obj.cfg.realign_unwarp_param; ... - { obj.unwarp }, obj.cfg.realign_unwarp; ... - { 'rp_', ['rp_' obj.stc] }, obj.cfg.real_param; ... + { 'segparam_' }, obj.cfg.segment.param; ... + { obj.stc, [obj.unwarp, obj.stc]}, obj.cfg.stc; ... + { 'unwarpparam_' }, obj.cfg.realign_unwarp_param; ... + { obj.unwarp }, obj.cfg.realign_unwarp; ... + { 'rp_', ['rp_' obj.stc] }, obj.cfg.real_param; ... { 'mean', ... ['mean' obj.unwarp], ... - ['mean' obj.unwarp, obj.stc] }, obj.cfg.mean; ... + ['mean' obj.unwarp, obj.stc] }, obj.cfg.mean; ... { obj.norm, ... [obj.norm, obj.bias_cor], ... [obj.norm, obj.unwarp, obj.stc], ... [obj.norm, obj.realign, obj.stc], ... [obj.norm, obj.unwarp], ... - [obj.norm, obj.realign] }, obj.cfg.preproc_norm; ... - { [obj.norm, 'mean', obj.unwarp] }, obj.cfg.normalized_mean; ... - { [obj.norm, 'c1'] }, obj.cfg.segment.gm_norm; ... - { [obj.norm, 'c2'] }, obj.cfg.segment.wm_norm; ... - { [obj.norm, 'c3'] }, obj.cfg.segment.csf_norm; ... + [obj.norm, obj.realign] }, obj.cfg.preproc_norm; ... + { [obj.norm, 'mean', obj.unwarp] }, obj.cfg.normalized_mean; ... + { [obj.norm, 'c1'] }, obj.cfg.segment.gm_norm; ... + { [obj.norm, 'c2'] }, obj.cfg.segment.wm_norm; ... + { [obj.norm, 'c3'] }, obj.cfg.segment.csf_norm; ... {[obj.smooth, obj.norm], ... [obj.smooth, obj.norm, obj.unwarp, obj.stc], ... [obj.smooth, obj.norm, obj.realign, obj.stc], ... @@ -198,8 +197,7 @@ [obj.smooth, obj.unwarp, obj.stc], ... [obj.smooth, obj.realign, obj.stc], ... [obj.smooth, obj.unwarp], ... - [obj.smooth, obj.realign]}, obj.cfg.smooth - }; + [obj.smooth, obj.realign]}, obj.cfg.smooth}; for i_map = 1:size(prfx_spec, 1) obj = obj.add_mapping('prefix', prfx_spec{i_map, 1}, ... diff --git a/tests/test_spm_2_bids.m b/tests/test_spm_2_bids.m index 82ee2ac..92095cf 100644 --- a/tests/test_spm_2_bids.m +++ b/tests/test_spm_2_bids.m @@ -92,6 +92,10 @@ function test_spm_2_bids_no_prefix() function test_spm_2_bids_unknown_prefix() + if is_octave() + return + end + file = 'wtfsub-01_ses-02_T1w.nii'; assertWarning( ... @()spm_2_bids(file), ... From f5c1af9cce8b5e87ee09394e646798c04ff89598 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 12:06:04 +0100 Subject: [PATCH 18/19] fix default slice timing prefix --- src/defaults/get_spm_prefix_list.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defaults/get_spm_prefix_list.m b/src/defaults/get_spm_prefix_list.m index 2ce68c7..9636174 100644 --- a/src/defaults/get_spm_prefix_list.m +++ b/src/defaults/get_spm_prefix_list.m @@ -8,7 +8,7 @@ try spm_defaults = spm_get_defaults(); catch - spm_defaults.slicetiming.prefix = 's'; + spm_defaults.slicetiming.prefix = 'a'; spm_defaults.realign.write.prefix = 'r'; spm_defaults.unwarp.write.prefix = 'u'; spm_defaults.coreg.write.prefix = 'r'; From c44291bfdd0f2c42e407342ab574ff877bba9cf4 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Fri, 28 Jan 2022 12:14:34 +0100 Subject: [PATCH 19/19] fix doc --- docs/Makefile | 3 --- src/defaults/check_cfg.m | 34 +++++++++++++++++----------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 8996f31..d0c3cbf 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -18,6 +18,3 @@ help: # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -doc: - @$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)" diff --git a/src/defaults/check_cfg.m b/src/defaults/check_cfg.m index f514c89..75b8b80 100644 --- a/src/defaults/check_cfg.m +++ b/src/defaults/check_cfg.m @@ -14,29 +14,31 @@ % % - :cfg: the option structure with missing values filled in by the defaults. % - % ``cfg`` fields:: + % ``cfg`` fields: % - % :param entity_order: order of the entities in bids derivatives - % :param fwhm: value to append to smoothing desctiption label - % :param spec: specfication details to over ride some of the defaults + % - ``entity_order``: order of the entities in bids derivatives + % - ``fwhm``: value to append to smoothing desctiption label + % - ``spec``: specfication details to over ride some of the defaults % % BIDS derivatives defining fields: % % Each of those fields contain a structure that lists the BIDS suffix % and entities-label pairs for each type of preprocessed image. % - % :param segment: - % :param stc: - % :param realign_unwarp: - % :param real_param: - % :param mean: - % :param normalized_mean: - % :param preproc: - % :param preproc_norm: - % :param smooth: - % :param smooth_norm: + % - ``segment`` + % - ``stc`` + % - ``realign_unwarp`` + % - ``real_param`` + % - ``mean`` + % - ``normalized_mean`` + % - ``preproc`` + % - ``preproc_norm`` + % - ``smooth`` + % - ``smooth_norm`` % - % For example:: + % For example: + % + % .. code-block:: matlab % % % for grey matter segmentation output % cfg.segment.gm = struct('entities', struct('space', 'individual', ... @@ -44,8 +46,6 @@ % 'suffix', 'probseg') % % - % :mapping: a n X 2 cell that maps a prefix ``mapping{i, 1}`` to a - % to a given bids-derivatives name specification ``mapping{i, 2}`` % % (C) Copyright 2021 spm_2_bids developers