diff --git a/.github/workflows/system_tests_bms.m b/.github/workflows/system_tests_bms.m new file mode 100644 index 000000000..6093cb191 --- /dev/null +++ b/.github/workflows/system_tests_bms.m @@ -0,0 +1,12 @@ +% +% (C) Copyright 2023 bidspm developers + +root_dir = getenv('GITHUB_WORKSPACE'); + +fprintf('\nroot dir is %s\n', root_dir); + +addpath(fullfile(root_dir, 'spm12')); + +cd(fullfile(root_dir, 'demos', 'bayes')); + +run ds000114_run; diff --git a/.github/workflows/tests_bayes.yml b/.github/workflows/tests_bayes.yml new file mode 100644 index 000000000..d28f736f8 --- /dev/null +++ b/.github/workflows/tests_bayes.yml @@ -0,0 +1,87 @@ +--- +name: tests bayesian model selection + +# Uses the cron schedule for github actions +# +# https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#scheduled-events +# +# ┌───────────── minute (0 - 59) +# │ ┌───────────── hour (0 - 23) +# │ │ ┌───────────── day of the month (1 - 31) +# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) +# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) +# │ │ │ │ │ +# │ │ │ │ │ +# │ │ │ │ │ +# * * * * * + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: 0 0 1,15 * * + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + + tests: + + if: github.repository_owner == 'cpp-lln-lab' + + runs-on: ubuntu-latest + + steps: + + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + sudo apt-get -y -qq update + sudo apt-get install -y git-annex + python -m pip install --upgrade pip setuptools + pip install datalad + + - name: Get data + run: make -C demos/bayes data_ds000114 + + - name: Clone bidspm + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install validators + run: make install + + - name: Install SPM + run: | + git clone https://github.com/spm/spm12.git --depth 1 + + - name: Copy Macs toolbox to SPM inputs_folder + run: cp -rv lib/MACS spm12/toolbox/MACS + + - name: Install MATLAB + uses: matlab-actions/setup-matlab@v1.2.4 + with: + release: R2022b + + - name: Run system tests MATLAB BMS + uses: matlab-actions/run-command@v1.2.1 + with: + command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run system_tests_bms}; diff --git a/demos/bayes/ds000114_run.m b/demos/bayes/ds000114_run.m index 7bae78da0..6a53031de 100644 --- a/demos/bayes/ds000114_run.m +++ b/demos/bayes/ds000114_run.m @@ -17,7 +17,7 @@ FWHM = 8; % to run on fewer subjects -TESTING = false; +TESTING = true; % The directory where the data are located root_dir = fileparts(mfilename('fullpath')); diff --git a/src/cli/cliCreateRoi.m b/src/cli/cliCreateRoi.m index f3f1a60f7..ddf16c02d 100644 --- a/src/cli/cliCreateRoi.m +++ b/src/cli/cliCreateRoi.m @@ -18,7 +18,7 @@ function cliCreateRoi(varargin) 'pipelineType', 'create_roi', ... 'verbosity', 0); - if opt.boilerplate_only + if opt.boilerplateOnly return end diff --git a/src/cli/cliPreprocess.m b/src/cli/cliPreprocess.m index ef2590384..ae6301983 100644 --- a/src/cli/cliPreprocess.m +++ b/src/cli/cliPreprocess.m @@ -37,7 +37,7 @@ function cliPreprocess(varargin) 'outputPath', fullfile(opt.dir.output, 'reports'), ... 'pipelineType', 'preprocess', ... 'verbosity', 0); - if opt.boilerplate_only + if opt.boilerplateOnly return end diff --git a/src/cli/cliStats.m b/src/cli/cliStats.m index c179678fa..fd987943a 100644 --- a/src/cli/cliStats.m +++ b/src/cli/cliStats.m @@ -58,7 +58,7 @@ function cliStats(varargin) 'outputPath', fullfile(opt.dir.output, 'reports'), ... 'pipelineType', 'stats', ... 'verbosity', 0); - if opt.boilerplate_only + if opt.boilerplateOnly continue end diff --git a/src/cli/getOptionsFromCliArgument.m b/src/cli/getOptionsFromCliArgument.m index 541bd05f9..6b6a76275 100644 --- a/src/cli/getOptionsFromCliArgument.m +++ b/src/cli/getOptionsFromCliArgument.m @@ -40,7 +40,7 @@ end if isfield(args.Results, 'boilerplate_only') - opt.boilerplate_only = args.Results.boilerplate_only; + opt.boilerplateOnly = args.Results.boilerplate_only; end if isfield(args.Results, 'dry_run') @@ -198,6 +198,9 @@ end function opt = overrideSpace(opt, args) + if ~isfield(args.Results, 'space') + return + end if ~isempty(args.Results.space) if isfield(opt, 'space') && ~all(ismember(args.Results.space, opt.space)) overrideMsg('space', convertToString(args.Results.space), ... diff --git a/src/cli/inputParserForCreateModel.m b/src/cli/inputParserForCreateModel.m index 80499b35a..c3a8b64b2 100644 --- a/src/cli/inputParserForCreateModel.m +++ b/src/cli/inputParserForCreateModel.m @@ -8,6 +8,7 @@ args = baseInputParser(); isEmptyOrCellstr = @(x) isempty(x) || iscellstr(x); %#ok<*ISCLSTR> + isCellStr = @(x) iscellstr(x); addParameter(args, 'space', {}, isCellStr); addParameter(args, 'task', {}, isEmptyOrCellstr); diff --git a/src/cli/inputParserForStats.m b/src/cli/inputParserForStats.m index 6848e9527..252341399 100644 --- a/src/cli/inputParserForStats.m +++ b/src/cli/inputParserForStats.m @@ -29,6 +29,7 @@ addParameter(args, 'design_only', false, isLogical); addParameter(args, 'concatenate', false, isLogical); addParameter(args, 'keep_residuals', false, isLogical); + addParameter(args, 'use_dummy_regressor', false, isLogical); addParameter(args, 'roi_atlas', 'neuromorphometrics', isInAvailableAtlas); diff --git a/src/defaults/checkOptions.m b/src/defaults/checkOptions.m index 5c8ea1881..a46797d23 100644 --- a/src/defaults/checkOptions.m +++ b/src/defaults/checkOptions.m @@ -65,7 +65,7 @@ % - ``opt.pipeline.isBms`` whether this is a bayesion model selection % pipeline % - % - ``opt.boilerplate_only = false`` - + % - ``opt.boilerplateOnly = false`` - % If set to ``true`` only creates dataset description reports and methods description. % Overwrites previous versions. % @@ -267,7 +267,7 @@ fieldsToSet.pipeline.name = 'bidspm'; fieldsToSet.pipeline.isBms = false; - fieldsToSet.boilerplate_only = false; + fieldsToSet.boilerplateOnly = false; fieldsToSet.useBidsSchema = false; diff --git a/src/messages/bidspmHelp.m b/src/messages/bidspmHelp.m index 59fbe4519..ee882c2b6 100644 --- a/src/messages/bidspmHelp.m +++ b/src/messages/bidspmHelp.m @@ -306,6 +306,7 @@ function bidspmHelp() % 'design_only', false, ... % 'ignore', {}, ... % 'concatenate', false, ... + % 'use_dummy_regressor', false) % 'skip_validation', false) % % @@ -359,9 +360,14 @@ function bidspmHelp() % :param roi_name: Names or regex expression of the ROI to use. % :type roi_name: cell string % - % :param boilerplate_only: Only creates dataset description reports. - % and methods description. Defaults to ``false``. - % :type boilerplate_only: logical + % :param boilerplate_only: Only creates dataset description reports. + % and methods description. Defaults to ``false``. + % :type boilerplate_only: logical + % + % :param use_dummy_regressor: If true any missing condition will be modelled + % by a dummy regressor of ``NaN``. + % Defaults to ``false``. + % :type use_dummy_regressor: logical % % % @@ -393,7 +399,7 @@ function bidspmHelp() % % For the bayesian model selection to function % you must first specify all your models using the ``'specify_only'`` action - % with the options ``useDummyRegressor = true``. + % with the options ``'use_dummy_regressor', true``. % % .. code-block:: matlab % @@ -401,11 +407,11 @@ function bidspmHelp() % % bidspm(bids_dir, output_dir, 'subject', ... % 'participant_label', participant_label, ... - % 'action', 'specify_only', ... % 'preproc_dir', preproc_dir, ... + % 'action', 'specify_only', ... % 'model_file', models_dir, ... - % 'fwhm', FWHM, ... - % 'options', opt); + % 'use_dummy_regressor', true + % 'fwhm', FWHM); % % % **low level calls** diff --git a/src/workflows/bidsReport.m b/src/workflows/bidsReport.m index 818c0e4ba..143df54b5 100644 --- a/src/workflows/bidsReport.m +++ b/src/workflows/bidsReport.m @@ -22,7 +22,7 @@ function bidsReport(opt) opt.pipeline.type = 'preproc'; - if ~opt.boilerplate_only && ... + if ~opt.boilerplateOnly && ... isdir(fullfile(opt.dir.output, 'reports')) logger('INFO', 'Dataset reports already exist.', ... 'options', opt, ...