-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow string inputs for most interfaces (#522)
* Support optional string arguments Can now provide double-quoted string paths and options to generate, export, and read functions. * Adds string checks for all filename references * Refactor generate, export, and read functions --------- Co-authored-by: Lawrence Niu <[email protected]>
- Loading branch information
1 parent
461c5c4
commit 0d334ed
Showing
8 changed files
with
320 additions
and
285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,55 @@ | ||
function generateCore(varargin) | ||
% GENERATECORE Generate Matlab classes from NWB core schema files | ||
% GENERATECORE() Generate classes (Matlab m-files) from the | ||
% NWB:N core namespace file. By default, generates off of the most recent nwb-schema | ||
% release. | ||
% | ||
% GENERATECORE(version) Generate classes for the | ||
% core namespace of the listed version. | ||
% | ||
% A cache of schema data is generated in the 'namespaces' subdirectory in | ||
% the current working directory. This is for allowing cross-referencing | ||
% classes between multiple namespaces. | ||
% | ||
% Output files are generated placed in a '+types' subdirectory in the | ||
% current working directory. | ||
% | ||
% GENERATECORE(__, 'savedir', saveDirectory) Generates the core class | ||
% files in the specified directory. | ||
% | ||
% Example: | ||
% generateCore(); | ||
% generateCore('2.2.3'); | ||
% | ||
% See also GENERATEEXTENSION | ||
|
||
latestVersion = '2.6.0'; | ||
|
||
if nargin == 0 || strcmp(varargin{1}, 'savedir') | ||
version = latestVersion; | ||
else | ||
version = varargin{1}; | ||
varargin = varargin(2:end); | ||
validateattributes(version, {'char'}, {'scalartext'}); | ||
end | ||
|
||
if strcmp(version, 'latest') | ||
version = latestVersion; | ||
end | ||
|
||
schemaPath = fullfile(misc.getMatnwbDir(), 'nwb-schema', version); | ||
corePath = fullfile(schemaPath, 'core', 'nwb.namespace.yaml'); | ||
commonPath = fullfile(schemaPath,... | ||
'hdmf-common-schema', ... | ||
'common',... | ||
'namespace.yaml'); | ||
assert(2 == exist(corePath, 'file'),... | ||
'NWB:GenerateCore:MissingCoreSchema',... | ||
'Cannot find suitable core namespace for schema version `%s`',... | ||
version); | ||
if 2 == exist(commonPath, 'file') | ||
generateExtension(commonPath, varargin{:}); | ||
end | ||
generateExtension(corePath, varargin{:}); | ||
% GENERATECORE Generate Matlab classes from NWB core schema files | ||
% GENERATECORE() Generate classes (Matlab m-files) from the | ||
% NWB:N core namespace file. By default, generates off of the most recent nwb-schema | ||
% release. | ||
% | ||
% GENERATECORE(version) Generate classes for the | ||
% core namespace of the listed version. | ||
% | ||
% A cache of schema data is generated in the 'namespaces' subdirectory in | ||
% the current working directory. This is for allowing cross-referencing | ||
% classes between multiple namespaces. | ||
% | ||
% Output files are generated placed in a '+types' subdirectory in the | ||
% current working directory. | ||
% | ||
% GENERATECORE(__, 'savedir', saveDirectory) Generates the core class | ||
% files in the specified directory. | ||
% | ||
% Example: | ||
% generateCore(); | ||
% generateCore('2.2.3'); | ||
% | ||
% See also GENERATEEXTENSION | ||
|
||
latestVersion = '2.6.0'; | ||
|
||
if nargin == 0 || strcmp(varargin{1}, 'savedir') | ||
version = latestVersion; | ||
else | ||
version = varargin{1}; | ||
validateattributes(version, {'char', 'string'}, {'scalartext'}, 'generateCore', 'version', 1); | ||
version = char(version); | ||
varargin = varargin(2:end); | ||
end | ||
|
||
if strcmp(version, 'latest') | ||
version = latestVersion; | ||
end | ||
|
||
schemaPath = fullfile(misc.getMatnwbDir(), 'nwb-schema', version); | ||
corePath = fullfile(schemaPath, 'core', 'nwb.namespace.yaml'); | ||
commonPath = fullfile(schemaPath,... | ||
'hdmf-common-schema', ... | ||
'common',... | ||
'namespace.yaml'); | ||
assert(2 == exist(corePath, 'file'),... | ||
'NWB:GenerateCore:MissingCoreSchema',... | ||
'Cannot find suitable core namespace for schema version `%s`',... | ||
version); | ||
if 2 == exist(commonPath, 'file') | ||
generateExtension(commonPath, varargin{:}); | ||
end | ||
generateExtension(corePath, varargin{:}); | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,62 @@ | ||
function generateExtension(varargin) | ||
% GENERATEEXTENSION Generate Matlab classes from NWB extension schema file | ||
% GENERATEEXTENSION(extension_path...) Generate classes | ||
% (Matlab m-files) from one or more NWB:N schema extension namespace | ||
% files. A registry of already generated core types is used to resolve | ||
% dependent types. | ||
% | ||
% A cache of schema data is generated in the 'namespaces' subdirectory in | ||
% the current working directory. This is for allowing cross-referencing | ||
% classes between multiple namespaces. | ||
% | ||
% Output files are generated placed in a '+types' subdirectory in the | ||
% current working directory. | ||
% | ||
% Example: | ||
% generateExtension('schema\myext\myextension.namespace.yaml', 'schema\myext2\myext2.namespace.yaml'); | ||
% | ||
% See also GENERATECORE | ||
assert(iscellstr(varargin),... | ||
'NWB:GenerateExtension:InvalidArguments',... | ||
'Must be a cell array of strings.'); %#ok<ISCLSTR> | ||
|
||
saveDirMask = strcmp(varargin, 'savedir'); | ||
if any(saveDirMask) | ||
assert(~saveDirMask(end),... | ||
'NWB:GenerateExtenion:InvalidParameter',... | ||
'savedir must be paired with the desired save directory.'); | ||
saveDir = varargin{find(saveDirMask, 1, 'last') + 1}; | ||
saveDirParametersMask = saveDirMask | circshift(saveDirMask, 1); | ||
sourceList = varargin(~saveDirParametersMask); | ||
else | ||
saveDir = misc.getMatnwbDir(); | ||
sourceList = varargin; | ||
end | ||
|
||
for iNamespaceFiles = 1:length(sourceList) | ||
source = sourceList{iNamespaceFiles}; | ||
validateattributes(source, {'char', 'string'}, {'scalartext'}); | ||
% GENERATEEXTENSION Generate Matlab classes from NWB extension schema file | ||
% GENERATEEXTENSION(extension_path...) Generate classes | ||
% (Matlab m-files) from one or more NWB:N schema extension namespace | ||
% files. A registry of already generated core types is used to resolve | ||
% dependent types. | ||
% | ||
% A cache of schema data is generated in the 'namespaces' subdirectory in | ||
% the current working directory. This is for allowing cross-referencing | ||
% classes between multiple namespaces. | ||
% | ||
% Output files are generated placed in a '+types' subdirectory in the | ||
% current working directory. | ||
% | ||
% Example: | ||
% generateExtension('schema\myext\myextension.namespace.yaml', 'schema\myext2\myext2.namespace.yaml'); | ||
% | ||
% See also GENERATECORE | ||
|
||
[localpath, ~, ~] = fileparts(source); | ||
assert(2 == exist(source, 'file'),... | ||
'NWB:GenerateExtension:FileNotFound', 'Path to file `%s` could not be found.', source); | ||
fid = fopen(source); | ||
namespaceText = fread(fid, '*char') .'; | ||
fclose(fid); | ||
for iOption = 1:length(varargin) | ||
option = varargin{iOption}; | ||
validateattributes(option, {'char', 'string'}, {'scalartext'} ... | ||
, 'generateExtension', 'extension name', iOption); | ||
if isstring(option) | ||
varargin{iOption} = char(option); | ||
end | ||
end | ||
|
||
Namespaces = spec.generate(namespaceText, localpath); | ||
|
||
for iNamespace = 1:length(Namespaces) | ||
Namespace = Namespaces(iNamespace); | ||
spec.saveCache(Namespace, saveDir); | ||
file.writeNamespace(Namespace.name, saveDir); | ||
rehash(); | ||
saveDirMask = strcmp(varargin, 'savedir'); | ||
if any(saveDirMask) | ||
assert(~saveDirMask(end),... | ||
'NWB:GenerateExtenion:InvalidParameter',... | ||
'savedir must be paired with the desired save directory.'); | ||
saveDir = varargin{find(saveDirMask, 1, 'last') + 1}; | ||
saveDirParametersMask = saveDirMask | circshift(saveDirMask, 1); | ||
sourceList = varargin(~saveDirParametersMask); | ||
else | ||
saveDir = misc.getMatnwbDir(); | ||
sourceList = varargin; | ||
end | ||
|
||
for iNamespaceFiles = 1:length(sourceList) | ||
source = sourceList{iNamespaceFiles}; | ||
validateattributes(source, {'char', 'string'}, {'scalartext'}); | ||
|
||
[localpath, ~, ~] = fileparts(source); | ||
assert(2 == exist(source, 'file'),... | ||
'NWB:GenerateExtension:FileNotFound', 'Path to file `%s` could not be found.', source); | ||
fid = fopen(source); | ||
namespaceText = fread(fid, '*char') .'; | ||
fclose(fid); | ||
|
||
Namespaces = spec.generate(namespaceText, localpath); | ||
|
||
for iNamespace = 1:length(Namespaces) | ||
Namespace = Namespaces(iNamespace); | ||
spec.saveCache(Namespace, saveDir); | ||
file.writeNamespace(Namespace.name, saveDir); | ||
rehash(); | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,44 @@ | ||
function nwbExport(nwb, filenames) | ||
%NWBEXPORT Writes an NWB file. | ||
% nwbRead(nwb,filename) Writes the nwb object to a file at filename. | ||
% | ||
% Example: | ||
% % Generate Matlab code for the NWB objects from the core schema. | ||
% % This only needs to be done once. | ||
% generateCore('schema\core\nwb.namespace.yaml'); | ||
% % Create some fake fata and write | ||
% nwb = NwbFile; | ||
% nwb.session_start_time = datetime('now'); | ||
% nwb.identifier = 'EMPTY'; | ||
% nwb.session_description = 'empty test file'; | ||
% nwbExport(nwb, 'empty.nwb'); | ||
% | ||
% See also GENERATECORE, GENERATEEXTENSION, NWBFILE, NWBREAD | ||
validateattributes(nwb, {'NwbFile'}, {'nonempty'}); | ||
validateattributes(filenames, {'cell', 'string', 'char'}, {'nonempty'}); | ||
if iscell(filenames) | ||
assert(iscellstr(filenames), 'filename cell array must consist of strings'); | ||
end | ||
if ~isscalar(nwb) | ||
assert(~ischar(filenames) && length(filenames) == length(nwb), ... | ||
'NwbFile and filename array dimensions must match.'); | ||
end | ||
|
||
for i=1:length(nwb) | ||
if iscellstr(filenames) | ||
filename = filenames{i}; | ||
elseif isstring(filenames) | ||
filename = filenames(i); | ||
else | ||
filename = filenames; | ||
%NWBEXPORT Writes an NWB file. | ||
% nwbRead(nwb,filename) Writes the nwb object to a file at filename. | ||
% | ||
% Example: | ||
% % Generate Matlab code for the NWB objects from the core schema. | ||
% % This only needs to be done once. | ||
% generateCore('schema\core\nwb.namespace.yaml'); | ||
% % Create some fake fata and write | ||
% nwb = NwbFile; | ||
% nwb.session_start_time = datetime('now'); | ||
% nwb.identifier = 'EMPTY'; | ||
% nwb.session_description = 'empty test file'; | ||
% nwbExport(nwb, 'empty.nwb'); | ||
% | ||
% See also GENERATECORE, GENERATEEXTENSION, NWBFILE, NWBREAD | ||
validateattributes(nwb, {'NwbFile'}, {'nonempty'}, 'nwbExport', 'nwb', 1); | ||
validateattributes(filenames, {'cell', 'string', 'char'}, {'nonempty'}, 'nwbExport', 'filenames', 2); | ||
if isstring(filenames) | ||
filenames = convertStringsToChars(filenames); | ||
end | ||
if iscell(filenames) | ||
for iName = 1:length(filenames) | ||
name = filenames{iName}; | ||
validateattributes(name, {'string', 'char'}, {'scalartext', 'nonempty'} ... | ||
, 'nwbExport', 'filenames', 2); | ||
filenames{iName} = char(name); | ||
end | ||
end | ||
if ~isscalar(nwb) | ||
assert(~ischar(filenames) && length(filenames) == length(nwb), ... | ||
'NwbFile and filename array dimensions must match.'); | ||
end | ||
|
||
nwb(i).export(filename); | ||
end | ||
for iFiles = 1:length(nwb) | ||
if iscellstr(filenames) | ||
filename = filenames{iFiles}; | ||
else | ||
filename = filenames; | ||
end | ||
|
||
nwb(iFiles).export(filename); | ||
end | ||
end |
Oops, something went wrong.