diff --git a/README.md b/README.md index 035a693f..802c1490 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -**BIDS validator and linter** - -[![Build Status](https://travis-ci.com/cpp-lln-lab/CPP_BIDS.svg?branch=master)](https://travis-ci.com/cpp-lln-lab/CPP_BIDS) - **Unit tests and coverage** [![](https://img.shields.io/badge/Octave-CI-blue?logo=Octave&logoColor=white)](https://github.com/cpp-lln-lab/CPP_BIDS/actions) @@ -9,6 +5,10 @@ [![codecov](https://codecov.io/gh/cpp-lln-lab/CPP_BIDS/branch/master/graph/badge.svg)](https://codecov.io/gh/cpp-lln-lab/CPP_BIDS) +**BIDS validator and linter** + +[![Build Status](https://travis-ci.com/cpp-lln-lab/CPP_BIDS.svg?branch=master)](https://travis-ci.com/cpp-lln-lab/CPP_BIDS) + **Contributors** [![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-) @@ -30,6 +30,7 @@ - [saveEventsFile](#saveeventsfile) - [checkCFG](#checkcfg) - [CFG content](#cfg-content) + - [createBoldJson](#createboldjson) - [How to install](#how-to-install) - [Download with git](#download-with-git) - [Add as a submodule](#add-as-a-submodule) @@ -297,6 +298,26 @@ cfg.fileName.datasetDescription ``` +### createBoldJson + +``` +createBoldJson(cfg) +``` + +This function creates a very light-weight version of the side-car JSON file for a BOLD functional run. + +This will only contain the minimum BIDS requirement and will likely be less complete than the info you could from DICOM conversion. + +If you put the following line at the end of your experiment script, it will dump the content of the `extraInfo` structure in the json file. + +``` +createBoldJson(cfg, extraInfo) +``` + +This allows to add all the parameters that you used to run your experiment in a human readable format: so that when you write your methods sections 2 years later ("the reviewer asked me for the size of my fixation cross... FML"), the info you used WHEN you ran the experiment is saved in an easily accessible text format. For the love of the flying spaghetti monster do not save all your parameters in a `.mat` file: think of the case when you won't have matlab or octave installed on a computer (plus not everyone uses those). + +Also to reading your experiment parameters, you won't have to read it from the `setParameters.m` file and wonder if those might have been modified when running the experiment and you did not commit and tagged that change with git. + ## How to install ### Download with git diff --git a/manualTests/testData/extra_bold.json b/manualTests/testData/extra_bold.json new file mode 100644 index 00000000..bb36cf1c --- /dev/null +++ b/manualTests/testData/extra_bold.json @@ -0,0 +1,10 @@ +{ + "Instructions": "", + "RepetitionTime": [], + "SliceTiming": [], + "TaskDescription": "", + "TaskName": "testtask", + "extraInfo": { + "nestedExtraInfo": "something extra" + } +} \ No newline at end of file diff --git a/manualTests/test_createBoldJson.m b/manualTests/test_createBoldJson.m new file mode 100644 index 00000000..6f58d49c --- /dev/null +++ b/manualTests/test_createBoldJson.m @@ -0,0 +1,50 @@ +function test_suite = test_createBoldJson %#ok<*STOUT> + try % assignment of 'localfunctions' is necessary in Matlab >= 2016 + test_functions = localfunctions(); %#ok<*NASGU> + catch % no problem; early Matlab versions can use initTestSuite fine + end + initTestSuite; +end + +function test_createBoldJsonExtra() + + outputDir = fullfile(fileparts(mfilename('fullpath')), 'output'); + + %% set up + + cfg.verbose = false; + + cfg.subject.subjectNb = 1; + cfg.subject.runNb = 1; + + cfg.task.name = 'testtask'; + + cfg.dir.output = outputDir; + + cfg.testingDevice = 'mri'; + + cfg = createFilename(cfg); + + logFile = saveEventsFile('init', cfg); %#ok<*NASGU> + + extraInfo = struct('extraInfo', struct('nestedExtraInfo', 'something extra')); + + createBoldJson(cfg, extraInfo); + + %% check content + fileName = strrep(cfg.fileName.events, '_events', '_bold'); + fileName = strrep(fileName, '.tsv', '.json'); + + actualStruct = bids.util.jsondecode(fullfile( ... + cfg.dir.outputSubject, ... + cfg.fileName.modality, ... + fileName)); + + % data to test against + expectedStruct = bids.util.jsondecode( ... + fullfile(pwd, 'testData', 'extra_bold.json')); + + % test + assertEqual(expectedStruct, actualStruct); + +end diff --git a/manualTests/test_makeRawDataset.m b/manualTests/test_makeRawDataset.m index 20b99ca7..d4a89d0c 100644 --- a/manualTests/test_makeRawDataset.m +++ b/manualTests/test_makeRawDataset.m @@ -29,7 +29,8 @@ function test_makeRawDataset() cfg = createFilename(cfg); - createBoldJson(cfg); + extraInfo = struct('extraInfo', struct('nestedExtraInfo', 'something extra')); + createBoldJson(cfg, extraInfo); createDatasetDescription(cfg); diff --git a/src/createBoldJson.m b/src/createBoldJson.m index 02895afc..e198c142 100644 --- a/src/createBoldJson.m +++ b/src/createBoldJson.m @@ -1,12 +1,18 @@ -function createBoldJson(cfg) - % createBoldJson(cfg) +function createBoldJson(cfg, extraInfo) + % createBoldJson(cfg, extraInfo) % % Creates the side car JSON file for a BOLD functional run. % This will only contain the minimum BIDS requirement and will likey be less % complete than the info you could from DICOM conversion. + % + % Extra content can be added to the JSON file opts.Indent = ' '; + if nargin < 2 + extraInfo = struct(); + end + fileName = strrep(cfg.fileName.events, '_events', '_bold'); fileName = strrep(fileName, '.tsv', '.json'); @@ -17,6 +23,15 @@ function createBoldJson(cfg) jsonContent = cfg.bids.mri; + % add content of extraInfo to the JSON content + if ~isstruct(extraInfo) + warning('additional info added to a json file must be a structure'); + end + fieldList = fieldnames(extraInfo); + for iField = 1:numel(fieldList) + jsonContent.(fieldList{iField}) = extraInfo.(fieldList{iField}); + end + bids.util.jsonencode(fileName, jsonContent, opts); end