diff --git a/bidscoin/bids.py b/bidscoin/bids.py index 8862ff7c..06b6674e 100644 --- a/bidscoin/bids.py +++ b/bidscoin/bids.py @@ -16,6 +16,7 @@ import pandas as pd import ast import datetime +import jsonschema from functools import lru_cache from pathlib import Path from typing import List, Set, Tuple, Union, Dict, Any, Iterable, NewType @@ -1156,7 +1157,7 @@ def check_template(bidsmap: Bidsmap) -> bool: bidsignore = bidsmap['Options']['bidscoin'].get('bidsignore', []) # Check all the datatypes in the bidsmap - LOGGER.info('Checking the bidsmap datatypes:') + LOGGER.verbose('Checking the template bidsmap datatypes:') for dataformat in bidsmap: if dataformat in ('$schema', 'Options'): continue for datatype in bidsmap[dataformat]: @@ -1182,10 +1183,19 @@ def check_template(bidsmap: Bidsmap) -> bool: LOGGER.warning(f"Missing '{suffix}' run-item in: bidsmap[{dataformat}][{datatype}] (NB: this may be fine / a deprecated item)") valid = False + # Validate against the json schema + with (templatefolder/'schema.json').open('r') as stream: + schema = json.load(stream) + try: + jsonschema.validate(bidsmap, schema) + except jsonschema.ValidationError as bidsmaperror: + LOGGER.warning(f"Invalid template bidsmap:\n{bidsmaperror}") + valid = False + if valid: - LOGGER.success('All datatypes in the bidsmap are valid') + LOGGER.success('All datatypes and options in the template bidsmap are valid') else: - LOGGER.warning('Not all datatypes in the bidsmap are valid') + LOGGER.warning('Not all datatypes and options in the template bidsmap are valid') return valid diff --git a/bidscoin/bidseditor.py b/bidscoin/bidseditor.py index ce973bae..56a51527 100755 --- a/bidscoin/bidseditor.py +++ b/bidscoin/bidseditor.py @@ -1669,6 +1669,7 @@ def bidseditor(bidsfolder: str, bidsmapfile: str='', templatefile: str=bidsmap_t # Obtain the initial bidsmap info template_bidsmap, templatefile = bids.load_bidsmap(templatefile, checks=(True, True, False)) input_bidsmap, bidsmapfile = bids.load_bidsmap(bidsmapfile, bidsfolder/'code'/'bidscoin') + bids.check_template(template_bidsmap) if input_bidsmap.get('Options'): template_bidsmap['Options'] = input_bidsmap['Options'] # Always use the options of the input bidsmap diff --git a/bidscoin/bidsmapper.py b/bidscoin/bidsmapper.py index 7bbefa74..3095d6b2 100755 --- a/bidscoin/bidsmapper.py +++ b/bidscoin/bidsmapper.py @@ -73,6 +73,7 @@ def bidsmapper(rawfolder: str, bidsfolder: str, bidsmapfile: str, templatefile: # Get the heuristics for filling the new bidsmap (NB: plugins are stored in the bidsmaps) bidsmap_old, bidsmapfile = bids.load_bidsmap(bidsmapfile, bidscoinfolder, plugins) template, _ = bids.load_bidsmap(templatefile, plugins=plugins, checks=(True, True, False)) + bids.check_template(template) # Create the new bidsmap as a copy / bidsmap skeleton with no data type entries (i.e. bidsmap with empty lists) if force and bidsmapfile.is_file(): diff --git a/bidscoin/heuristics/schema.json b/bidscoin/heuristics/schema.json index 412b8388..15ea1508 100644 --- a/bidscoin/heuristics/schema.json +++ b/bidscoin/heuristics/schema.json @@ -96,6 +96,9 @@ "meta": { "description": "The meta-data that will be appended to the json sidecar files produced by the plugin", "type": "object" + }, + "datasource": { + "description": "The data source that will be appended when loading the bidsmap" } }, "additionalProperties": false diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3229e833..ff52b129 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -15,9 +15,10 @@ - A `--cluster` option for running bidscoiner in parallel on a (DRMAA enabled) HPC - Option to exclude datatypes from being saved in bids/derivatives - A `bidsmap_bids2bids` template bidsmap for nibabel2bids to edit existing BIDS datasets -- A `bidscoiner.tsv` logfile containing a concise overview of all input to output file conversions +- A `bidscoiner.tsv` log-file containing a concise overview of all input to output file conversions - Integrated fslmaths preprocessing on slicereport input images - BIDScoin duecredit reports +- A new environment variable `BIDSCOIN_CONFIG=/writable/path/to/config.toml` for using a non-default config file ### Changed - `bidscoiner_plugin()` API: you can (should) return a personals dict (instead of writing it to `participants.tsv`) diff --git a/pyproject.toml b/pyproject.toml index c3b7228b..c689365f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ dependencies = ['pandas', 'python-dateutil', 'nibabel', 'bids-validator', + 'jsonschema', 'drmaa', 'duecredit']