From 53d0ab9136867bc2a3322d5a91ba1130eb04c0af Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 5 Aug 2020 12:09:47 +0200 Subject: [PATCH 1/3] allow createBoldJson to add extra content to a json file --- manualTests/testData/extra_bold.json | 10 ++++++ manualTests/test_createBoldJson.m | 50 ++++++++++++++++++++++++++++ manualTests/test_makeRawDataset.m | 3 +- src/createBoldJson.m | 19 +++++++++-- 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 manualTests/testData/extra_bold.json create mode 100644 manualTests/test_createBoldJson.m 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..70646d10 --- /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..f0fcd713 100644 --- a/src/createBoldJson.m +++ b/src/createBoldJson.m @@ -1,11 +1,17 @@ -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'); @@ -16,6 +22,15 @@ function createBoldJson(cfg) fileName); 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); From b8cb06605af1209d41f85fe757e6fb8e2ec805bf Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 5 Aug 2020 12:43:24 +0200 Subject: [PATCH 2/3] mh autofix --- manualTests/test_createBoldJson.m | 4 ++-- src/createBoldJson.m | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manualTests/test_createBoldJson.m b/manualTests/test_createBoldJson.m index 70646d10..6f58d49c 100644 --- a/manualTests/test_createBoldJson.m +++ b/manualTests/test_createBoldJson.m @@ -26,7 +26,7 @@ function test_createBoldJsonExtra() cfg = createFilename(cfg); logFile = saveEventsFile('init', cfg); %#ok<*NASGU> - + extraInfo = struct('extraInfo', struct('nestedExtraInfo', 'something extra')); createBoldJson(cfg, extraInfo); @@ -34,7 +34,7 @@ function test_createBoldJsonExtra() %% 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, ... diff --git a/src/createBoldJson.m b/src/createBoldJson.m index f0fcd713..e198c142 100644 --- a/src/createBoldJson.m +++ b/src/createBoldJson.m @@ -8,8 +8,8 @@ function createBoldJson(cfg, extraInfo) % Extra content can be added to the JSON file opts.Indent = ' '; - - if nargin<2 + + if nargin < 2 extraInfo = struct(); end @@ -22,11 +22,11 @@ function createBoldJson(cfg, extraInfo) fileName); 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 + 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}); From 0c03781dfc8190e1047530dd1a105f0f7e3a62c6 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 5 Aug 2020 12:57:28 +0200 Subject: [PATCH 3/3] update readme --- README.md | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) 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