diff --git a/examples/plot_validator.py b/examples/plot_validator.py new file mode 100644 index 000000000..403dd19df --- /dev/null +++ b/examples/plot_validator.py @@ -0,0 +1,13 @@ +import os.path as op + +from mne_bids.validator import validate_meg + +# test an _meg.json file: +json_fname = op.join('.', 'sub-01_task-audiovisual_meg.json') + +validate_meg(json_fname) + +# test an _fid.json file: +json_fname = op.join('.', 'sub-testme01_meg_fid.json') + +validate_meg(json_fname) diff --git a/examples/sub-01_task-audiovisual_meg.json b/examples/sub-01_task-audiovisual_meg.json new file mode 100644 index 000000000..1560036de --- /dev/null +++ b/examples/sub-01_task-audiovisual_meg.json @@ -0,0 +1,26 @@ +{ + "TaskName": "audiovisual", + "SamplingFrequency": 600.614990234, + "Manufacturer": "Elekta", + "ManufacturerModelName": "Neuromag Vectorview 306", + "TaskDescription": "In this experiment, checkerboard patterns were presented to the subject into the left and right visual field, interspersed by tones to the left or right ear. The interval between the stimuli was 750 ms. Occasionally a smiley face was presented at the center of the visual field. The subject was asked to press a key with the right index finger as soon as possible after the appearance of the face.", + "MEGChannelCount": 306, + "MEGREFChannelCount": 0, + "EEGChannelCount": 60, + "EOGChannelCount": 1, + "ECGChannelCount": 0, + "EMGChannelCount": 0, + "MiscChannelCount": 0, + "TriggerChannelCount": 9, + "PowerLineFrequency": 60, + "HLCFrequency": [], + "EEGReference": "nose", + "MEGPosition": "upright", + "OnlineFilters": "0.10000000149 Hz high-pass, 172.176300049 Hz low-pass", + "RecordingType": "continuous", + "EyesClosed": "false", + "ContinuousHeadLocalization": "false", + "DigitizedLandmarks": "true", + "DigitizedHeadPoints": "true", + "SubjectArtefactDescription": "false" +} diff --git a/examples/sub-testme01_meg_fid.json b/examples/sub-testme01_meg_fid.json new file mode 100644 index 000000000..9b0efb089 --- /dev/null +++ b/examples/sub-testme01_meg_fid.json @@ -0,0 +1,24 @@ +{ + "MEGCoordinateSystem": "not_empty", + "MEGCoordinateUnits": "not_empty", + "MEGCoordinateSystemDescription": "", + "EEGCoordinateSystem": "not_empty", + "EEGCoordinateUnits": "not_empty", + "EEGCoordinateSystemDescription": "", + "IntendedFor": "not_empty", + "AnatomicalMRICoordinateSystem": "not_empty", + "AnatomicalMRICoordinateUnits": "not_empty", + "AnatomicalMRICoordinateSystemDescription": "", + "CoilCoordinates": "not_empty", + "CoilCoordinateSystem": "not_empty", + "CoilCoordinateUnits": "not_empty", + "CoilCoordinateSystemDescription": "", + "LandmarkCoordinates": "not_empty", + "LandmarkCoordinateSystem": "not_empty", + "LandmarkCoordinateUnits": "not_empty", + "LandmarkCoordinateSystemDescription": "", + "DigitizedHeadPoints": "", + "DigitizedHeadPointsCoordinateSystem": "", + "DigitizedHeadPointsCoordinateUnits": "", + "DigitizedHeadPointsCoordinateSystemDescription": "" +} diff --git a/mne_bids/jsonschemas/schema_meg.json b/mne_bids/jsonschemas/schema_meg.json new file mode 100644 index 000000000..d45f2e88a --- /dev/null +++ b/mne_bids/jsonschemas/schema_meg.json @@ -0,0 +1,50 @@ +{ + "type": "object", + "properties": { + "TaskName": {"type": "string","minLength": 1}, + "Manufacturer": {"type": "string","minLength": 1}, + "ManufacturerModelName": {"type": "string"}, + "TaskDescription": {"type": "string"}, + "Instructions": {"type": "string"}, + "SamplingFrequency": {"type": "number"}, + "CogAtlasID": {"type": "string"}, + "CogPOID": {"type": "string"}, + "InstitutionName": {"type": "string"}, + "InstitutionAddress": {"type": "string"}, + "DeviceSerialNumber": {"type": "string"}, + "MEGChannelCount": {"type": "integer"}, + "MEGREFChannelCount": {"type": "integer"}, + "EEGChannelCount": {"type" : "integer"}, + "EOGChannelCount": {"type" : "integer"}, + "ECGChannelCount": {"type" : "integer"}, + "EMGChannelCount": {"type" : "integer"}, + "MiscChannelCount": {"type" : "integer"}, + "TriggerChannelCount": {"type" : "integer"}, + "PowerLineFrequency": {"type" : "number"}, + "EEGPlacementScheme": {"type" : "string"}, + "EEGReference": {"type" : "string"}, + "DewarPosition": {"type" : "string"}, + "SoftwareFilters": {"type" : "string"}, + "RecordingDuration": {"type" : "number"}, + "RecordingType": {"type" : "string"}, + "EpochLength": {"type" : ["number","string"]}, + "DeviceSoftwareVersion": {"type" : "string"}, + "ContinuousHeadLocalization": {"type" : "string"}, + "CoilFrequency": {"type" : "number"}, + "MaxMovement": {"type" : "number"}, + "SubjectArtefactDescription": {"type" : "string"}, + "DigitizedLandmarks": {"type" : "string"}, + "DigitizedHeadPoints": {"type" : "string"} + }, + "required": [ "TaskName", + "Manufacturer", + "SamplingFrequency", + "MEGChannelCount", + "MEGREFChannelCount", + "EEGChannelCount", + "EOGChannelCount", + "ECGChannelCount", + "EMGChannelCount", + "MiscChannelCount", + "TriggerChannelCount"] +} diff --git a/mne_bids/jsonschemas/schema_meg_fid.json b/mne_bids/jsonschemas/schema_meg_fid.json new file mode 100644 index 000000000..3f646addf --- /dev/null +++ b/mne_bids/jsonschemas/schema_meg_fid.json @@ -0,0 +1,41 @@ +{ + "type": "object", + "properties": { + "MEGCoordinateSystem": {"type": "string","minLength": 1}, + "MEGCoordinateUnits": {"type": "string","minLength": 1}, + "MEGCoordinateSystemDescription": {"type": "string"}, + "EEGCoordinateSystem": {"type": "string","minLength": 1}, + "EEGCoordinateUnits": {"type": "string","minLength": 1}, + "EEGCoordinateSystemDescription": {"type": "string"}, + "IntendedFor": {"type": "string","minLength": 1}, + "AnatomicalMRICoordinateSystem": {"type": "string","minLength": 1}, + "AnatomicalMRICoordinateUnits": {"type": "string","minLength": 1}, + "AnatomicalMRICoordinateSystemDescription": {"type": "string"}, + "CoilCoordinates": {"type": "string","minLength": 1}, + "CoilCoordinateSystem": {"type": "string","minLength": 1}, + "CoilCoordinateUnits": {"type": "string","minLength": 1}, + "CoilCoordinateSystemDescription": {"type": "string"}, + "LandmarkCoordinates": {"type": "string","minLength": 1}, + "LandmarkCoordinateSystem": {"type": "string","minLength": 1}, + "LandmarkCoordinateUnits": {"type": "string","minLength": 1}, + "LandmarkCoordinateSystemDescription": {"type": "string"}, + "DigitizedHeadPoints": {"type": "string"}, + "DigitizedHeadPointsCoordinateSystem": {"type": "string"}, + "DigitizedHeadPointsCoordinateUnits": {"type": "string"}, + "DigitizedHeadPointsCoordinateSystemDescription": {"type": "string"} + }, + "required": ["MEGCoordinateSystem", + "MEGCoordinateUnits", + "EEGCoordinateSystem", + "EEGCoordinateUnits", + "IntendedFor", + "AnatomicalMRICoordinateSystem", + "AnatomicalMRICoordinateUnits", + "CoilCoordinates", + "CoilCoordinateSystem", + "CoilCoordinateUnits", + "LandmarkCoordinates", + "LandmarkCoordinateSystem", + "LandmarkCoordinateUnits" + ] +} diff --git a/mne_bids/validator.py b/mne_bids/validator.py new file mode 100644 index 000000000..72ba051ce --- /dev/null +++ b/mne_bids/validator.py @@ -0,0 +1,27 @@ +import os.path as op +import inspect + +import json +from jsonschema import validate + +FILE = inspect.getfile(inspect.currentframe()) +base_dir = op.join(op.dirname(op.abspath(FILE)), 'jsonschemas') + + +def validate_meg(fname): + # get the correct schema + if fname.endswith('_meg.json'): + schema_fname = 'schema_meg.json' + elif fname.endswith('_fid.json'): + schema_fname = 'schema_meg_fid.json' + + # open the schema + with open(op.join(base_dir, schema_fname)) as json_data: + schema = json.load(json_data) + + # open the BIDS json file to validate + with open(fname) as json_data: + test_json = json.load(json_data) + + # validate it + validate(test_json, schema)