Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finalized the MATLAB HEDTools interface #20

Merged
merged 2 commits into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 4 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
[![Documentation Status](https://readthedocs.org/projects/hed-matlab/badge/?version=latest)](https://www.hed-matlab.org/en/latest/?badge=latest)
[![@HEDstandard](http://img.shields.io/twitter/follow/hedstandard.svg?style=social)](https://twitter.com/HEDstandard)

# HED-MATLAB
This repository contains the MATLAB supporting code infrastructure for Hierarchical Event Descriptors (HED).
This repository contains the MATLAB supporting code infrastructure
for Hierarchical Event Descriptors (HED).


### Installation of hedtools

The most of the Python-related resources in this repository
require the installation of the HEDTools Python module, which can be
installed using `pip` or directly from its GitHub repository as follows:

To use `pip` to install `hedtools` from PyPI:

```
pip install hedtools
```

To install directly from the
[GitHub](https://github.com/hed-standard/hed-python) repository:

```
pip install git+https://github.com/hed-standard/hed-python/@master
```

HEDTools require python 3.7 or greater.
The documentation for this repository can be found at
[**HED MATLAB Tools**](https://www.hed-resources.org/en/latest/HedMatlabTools.html).
8 changes: 4 additions & 4 deletions hedmat/hedtools/HedTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@
annotations = getHedAnnotations(obj, eventsIn, sidecar, ...
removeTypesOn, includeContext, replaceDefs);

factors = getHedFactors(obj, annotations, queries);
factors = searchHed(obj, annotations, queries);

issueString = validateEvents(obj, eventsIn, sidecar, checkWarnings);
issues = validateEvents(obj, eventsIn, sidecar, checkWarnings);

issueString = validateSidecar(obj, sidecar, checkWarnings);
issues = validateSidecar(obj, sidecar, checkWarnings);

issueString = validateTags(obj, hedtags, checkWarnings);
issues = validateTags(obj, hedtags, checkWarnings);

resetHedVersion(obj, hedVersion)
end
Expand Down
146 changes: 85 additions & 61 deletions hedmat/hedtools/HedToolsPython.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
obj.resetHedVersion(version)
end

function annotations = getHedAnnotations(obj, eventsIn, ...
sidecar, removeTypesOn, includeContext, replaceDefs)
function annotations = getHedAnnotations(obj, events, ...
sidecar, varargin)
% Return a cell array of HED annotations of same length as events.
%
% Parameters:
% eventsIn - char, string or rectified struct.
% events - char, string or rectified struct.
% sidecar - char, string or struct representing sidecar
% removeTypesOn - boolean true->remove Condition-variable
% and Task
% includeContext - boolean true->expand context (usually true).
% replaceDefs - boolean true->replace def with definition (usually true).
%
% Optional name-value:
% 'includeContext' - boolean true->expand context (usually true).
% 'removeTypesOn' - boolean true-> remove Condition-variable
% and Task
% 'replaceDefs' - boolean true->replace def with definition (usually true).
%
% Returns:
% annotations - cell array with the HED annotations.
Expand All @@ -38,23 +40,30 @@
% line.
%

events = HedToolsPython.getTabularObj(eventsIn, sidecar);
issueString = obj.validateEvents(events, sidecar, false);
p = inputParser;
p.addParameter('includeContext', true, @(x) islogical(x))
p.addParameter('removeTypesOn', true, @(x) islogical(x))
p.addParameter('replaceDefs', true, @(x) islogical(x))
parse(p, varargin{:});
eventsTab = HedToolsPython.getTabularObj(events, sidecar);
issueString = obj.validateEvents(eventsTab, sidecar, ...
'checkWarnings', false);
if ~isempty(issueString)
throw(MException( ...
'HedToolsPythonGetHedAnnotations:InvalidData', ...
"Input errors:\n" + issueString));
end
hedObjs = HedToolsPython.getHedStringObjs(events, ...
obj.HedSchema, removeTypesOn, includeContext, replaceDefs);
hedObjs = HedToolsPython.getHedStringObjs(eventsTab, ...
obj.HedSchema, p.Results.removeTypesOn, ...
p.Results.includeContext, p.Results.replaceDefs);
strs = ...
py.hed.tools.analysis.annotation_util.to_strlist(hedObjs);
cStrs = cell(strs);
% Convert each string object in the cell array to a char array
annotations = cellfun(@char, cStrs(:), 'UniformOutput', false);
end

function factors = getHedFactors(obj, annotations, queries)
function factors = searchHed(obj, annotations, queries)
%% Return an array of 0's and 1's indicating query truth
%
% Parameters:
Expand Down Expand Up @@ -83,118 +92,133 @@
factors = double(df_factors.to_numpy());
end

function [] = resetHedVersion(obj, version)
% Change the HED Version used.
%
% Parameters:
% version - cell array or char array or string with HED
% version specification.
obj.HedVersion = version;
obj.setHedSchema(version);
end

function [] = setHedSchema(obj, schema)
% Set a HedSchema or HedSchemaGroup object based on hedVersion
%
% Parameters:
% schema - a single string or a cell array of strings representing
% the HED schema version or a schema object.
%
obj.HedSchema = HedToolsPython.getHedSchemaObj(schema);
end

function issueString = validateEvents(obj, events, sidecar, checkWarnings)
function issues = validateEvents(obj, events, sidecar, varargin)
% Validate HED in events or other tabular-type input.
%
% Parameters:
% events - char array, string, struct (or tabularInput)
% sidecar - char, string or struct representing sidecar
% checkWarnings - Boolean indicating checking for warnings
%
% Optional name-value:
% 'checkWarnings' - boolean (optional, default false)
% indicates whether to include warnings.
% Returns:
% issueString - A string with the validation issues suitable for
% issues - A string with the validation issues suitable for
% printing (has newlines).

issueString = '';
sidecarObj = py.None;
p = inputParser;
p.addParameter('checkWarnings', false, @(x) islogical(x))
parse(p, varargin{:});
checkWarnings = p.Results.checkWarnings;
issues = '';
ehandler = py.hed.errors.error_reporter.ErrorHandler(...
check_for_warnings=checkWarnings);
if ~isempty(sidecar) && ~isequal(sidecar, py.None)
sidecar = HedTools.formatSidecar(sidecar);
sidecarObj = py.hed.tools.analysis.annotation_util.strs_to_sidecar(sidecar);
issues = sidecarObj.validate(obj.HedSchema, error_handler=ehandler);
issueString = ...
char(py.hed.get_printable_issue_string(issues));
if py.hed.errors.error_reporter.check_for_any_errors(issues)
hasErrors = py.hed.errors.error_reporter.check_for_any_errors(issues);
issues = char(py.hed.get_printable_issue_string(issues));
if hasErrors
return;
end
end
eventsObj = HedToolsPython.getTabularObj(events, sidecarObj);
issues = eventsObj.validate(obj.HedSchema, error_handler=ehandler);
issueString = [issueString, ...
char(py.hed.get_printable_issue_string(issues))];
issuesEvents = eventsObj.validate(obj.HedSchema, error_handler=ehandler);
issues = [issues, ...
char(py.hed.get_printable_issue_string(issuesEvents))];

end

function issueString = validateSidecar(obj, sidecar, checkWarnings)
function issues = validateSidecar(obj, sidecar, varargin)
% Validate a sidecar containing HED tags.
%
% Parameters:
% sidecar - a char, string, struct, or SidecarObj
% checkWarnings - boolean indicating checking for warnings
%
% Optional name-value:
% 'checkWarnings' - boolean (optional, default false)
% indicates whether to include warnings.
%
% Returns:
% issueString - A string with the validation issues suitable for
% printing (has newlines).
% issues - Char array with the validation issues suitable
% for printing (has newlines).

p = inputParser;
p.addParameter('checkWarnings', false, @(x) islogical(x))
parse(p, varargin{:});
ehandler = py.hed.errors.error_reporter.ErrorHandler(...
check_for_warnings=checkWarnings);
check_for_warnings=p.Results.checkWarnings);
sidecarObj = HedToolsPython.getSidecarObj(sidecar);
issues = sidecarObj.validate(obj.HedSchema, error_handler=ehandler);
if isempty(issues)
issueString = '';
issues = '';
else
issueString = ...
issues = ...
char(py.hed.get_printable_issue_string(issues));
end
end

function issueString = validateTags(obj, hedTags, checkWarnings)
function issues = validateTags(obj, hedTags, varargin)
% Validate a string containing HED tags.
%
% Parameters:
% hedTags - A MATLAB string or character array.
% checkWarnings - Boolean indicating checking for warnings
%
% Optional name-value:
% 'checkWarnings' - boolean (optional, default false)
% indicates whether to include warnings.
%
% Returns:
% issueString - A string with the validation issues suitable for
% issues - A string with the validation issues suitable for
% printing (has newlines).
% ToDo: Make hedDefinitions optional.
%

% vmod = py.importlib.import_module('hed.validator');

if ~ischar(hedTags) && ~isstring(hedTags)
throw(MException(...
'HedToolsPythonValidateHedTags:InvalidHedTagInput', ...
'HedToolsPythonValidateTags:InvalidHedTagInput', ...
'Must provide a string or char array as input'))
end

p = inputParser;
p.addParameter('checkWarnings', false, @(x) islogical(x))
parse(p, varargin{:});

hedStringObj = py.hed.HedString(hedTags, obj.HedSchema);
ehandler = py.hed.errors.error_reporter.ErrorHandler(...
check_for_warnings=checkWarnings);
check_for_warnings=p.Results.checkWarnings);
validator = ...
py.hed.validator.hed_validator.HedValidator(obj.HedSchema);
issues = ...
validator.validate(hedStringObj, false, ...
issues = validator.validate(hedStringObj, false, ...
error_handler=ehandler);
if isempty(issues)
issueString = '';
issues = '';
else
issueString = ...
issues = ...
char(py.hed.get_printable_issue_string(issues));
end
end

function [] = resetHedVersion(obj, version)
% Change the HED Version used.
%
% Parameters:
% version - cell array or char array or string with HED
% version specification.
obj.HedVersion = version;
obj.setHedSchema(version);
end

function [] = setHedSchema(obj, schema)
% Set a HedSchema or HedSchemaGroup object based on hedVersion
%
% Parameters:
% schema - a single string or a cell array of strings representing
% the HED schema version or a schema object.
%
obj.HedSchema = HedToolsPython.getHedSchemaObj(schema);
end

end

Expand Down
Loading