Skip to content
Draft
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
2 changes: 1 addition & 1 deletion +file/+internal/isPropertyHidden.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
if isa(propertyInfo, 'file.Attribute') || isa(propertyInfo, 'file.Dataset')
if strcmp(namespace.name, 'hdmf_common') ...
&& strcmp(className, 'VectorData') ...
&& any(strcmp(propertyInfo.name, {'unit', 'sampling_rate', 'resolution'}))
&& any(strcmp(propertyInfo.name, {'sampling_rate', 'resolution'}))
result = true;
else
result = false;
Expand Down
2 changes: 1 addition & 1 deletion +file/fillClass.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

if strcmp(namespace.name, 'hdmf_common') ...
&& strcmp(name, 'VectorData') ...
&& any(strcmp(prop.name, {'unit', 'sampling_rate', 'resolution'}))
&& any(strcmp(prop.name, {'sampling_rate', 'resolution'}))
hidden{end+1} = propertyName;
end
end
Expand Down
14 changes: 2 additions & 12 deletions +file/fillExport.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@
needsElisionGroupWrite = ~isempty(elideProps) ...
&& all(cellfun('isclass', elideProps, 'file.Group'));

if strcmp(propertyName, 'unit') && strcmp(RawClass.type, 'VectorData')
exportBody{end+1} = fillVectorDataUnitConditional();
elseif strcmp(propertyName, 'sampling_rate') && strcmp(RawClass.type, 'VectorData')
if strcmp(propertyName, 'sampling_rate') && strcmp(RawClass.type, 'VectorData')
exportBody{end+1} = fillVectorDataSamplingRateConditional();
elseif strcmp(propertyName, 'resolution') && strcmp(RawClass.type, 'VectorData')
exportBody{end+1} = fillVectorDataResolutionConditional();
Expand All @@ -63,14 +61,6 @@
, 'end'}, newline);
end

function exportBody = fillVectorDataUnitConditional()
exportBody = strjoin({...
'validUnitPaths = strcat(''units/'', {''waveform_mean'', ''waveform_sd'', ''waveforms''});' ...
, 'if ~isempty(obj.unit) && any(endsWith(fullpath, validUnitPaths))' ...
, ' writer.writeAttribute([fullpath ''/unit''], obj.unit);' ...
, 'end'}, newline);
end

function exportBody = fillVectorDataSamplingRateConditional()
exportBody = strjoin({...
'validDataSamplingPaths = strcat(''units/'', {''waveform_mean'', ''waveform_sd'', ''waveforms''});' ...
Expand Down Expand Up @@ -266,7 +256,7 @@
sprintf('obj.throwErrorIfRequiredDependencyMissing(''%s'', ''%s'', fullpath)', name, depPropname);
end

if prop.promoted_to_container
if prop.promoted_to_container && ~strcmp(prop.name, 'unit')
preExportString = sprintf([ ...
'if %s && %s && isobject(obj.%s) && isprop(obj.%s, ''%s'') && ~isempty(obj.%s.%s)\n' ...
' obj.%s = obj.%s.%s;\n' ...
Expand Down
2 changes: 1 addition & 1 deletion +file/fillSetters.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
propName, parentname);

syncPromotedDatasetAttributeString = '';
if prop.promoted_to_container
if prop.promoted_to_container && ~strcmp(prop.name, 'unit')
syncPromotedDatasetAttributeString = sprintf([ ...
'if ~isempty(obj.%1$s) && isobject(obj.%1$s) && isprop(obj.%1$s, ''%2$s'')\n' ...
' if ~isempty(obj.%3$s)\n' ...
Expand Down
12 changes: 0 additions & 12 deletions +file/processClass.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,6 @@
end

function class = patchVectorData(class)
%% Unit Attribute
% derived from schema 2.6.0
source = containers.Map();
source('name') = 'unit';
source('doc') = ['NOTE: this is a special value for compatibility with the Units table and is ' ...
'only written to file when detected to be in that specific HDF5 Group. ' ...
'The value must be ''volts'''];
source('dtype') = 'text';
source('value') = 'volts';
source('required') = false;
class.attributes(end+1) = file.Attribute(source);

%% Sampling Rate Attribute
% derived from schema 2.6.0

Expand Down
31 changes: 31 additions & 0 deletions +tests/+unit/+file/VectorDataPatchTest.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
classdef VectorDataPatchTest < tests.abstract.NwbTestCase

methods (Test)
function testVectorDataUnitIsNotInjected(testCase)
vectorDataClass = ?types.hdmf_common.VectorData;
vectorDataPropertyNames = {vectorDataClass.PropertyList.Name};

testCase.verifyFalse(ismember('unit', vectorDataPropertyNames))
testCase.verifyTrue(ismember('sampling_rate', vectorDataPropertyNames))
testCase.verifyTrue(ismember('resolution', vectorDataPropertyNames))

unitsClass = ?types.core.Units;
unitsPropertyNames = {unitsClass.PropertyList.Name};

testCase.verifyTrue(ismember('waveform_mean_unit', unitsPropertyNames))
testCase.verifyTrue(ismember('waveform_sd_unit', unitsPropertyNames))
testCase.verifyTrue(ismember('waveforms_unit', unitsPropertyNames))
end

function testUnitsDoesNotSyncPromotedUnitAttributesFromVectorData(testCase)
unitsFile = fullfile( ...
testCase.getTypesOutputFolder(), ...
'+types', '+core', 'Units.m');
unitsContents = string(fileread(unitsFile));

testCase.verifyFalse(contains(unitsContents, 'obj.waveform_mean.unit'))
testCase.verifyFalse(contains(unitsContents, 'obj.waveform_sd.unit'))
testCase.verifyFalse(contains(unitsContents, 'obj.waveforms.unit'))
end
end
end
9 changes: 0 additions & 9 deletions +types/+core/Units.m
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,6 @@ function postset_waveforms_sampling_rate(obj)
if ~isempty(obj.waveform_mean) && ~isa(obj.waveform_mean, 'types.untyped.SoftLink') && ~isa(obj.waveform_mean, 'types.untyped.ExternalLink') && ~isempty(obj.waveform_mean_sampling_rate)
writer.writeAttribute([fullpath '/waveform_mean/sampling_rate'], obj.waveform_mean_sampling_rate);
end
if isempty(obj.waveform_mean_unit) && ~isempty(obj.waveform_mean) && isobject(obj.waveform_mean) && isprop(obj.waveform_mean, 'unit') && ~isempty(obj.waveform_mean.unit)
obj.waveform_mean_unit = obj.waveform_mean.unit;
end
if ~isempty(obj.waveform_mean) && ~isa(obj.waveform_mean, 'types.untyped.SoftLink') && ~isa(obj.waveform_mean, 'types.untyped.ExternalLink') && ~isempty(obj.waveform_mean_unit)
writer.writeAttribute([fullpath '/waveform_mean/unit'], obj.waveform_mean_unit);
end
Expand All @@ -415,9 +412,6 @@ function postset_waveforms_sampling_rate(obj)
if ~isempty(obj.waveform_sd) && ~isa(obj.waveform_sd, 'types.untyped.SoftLink') && ~isa(obj.waveform_sd, 'types.untyped.ExternalLink') && ~isempty(obj.waveform_sd_sampling_rate)
writer.writeAttribute([fullpath '/waveform_sd/sampling_rate'], obj.waveform_sd_sampling_rate);
end
if isempty(obj.waveform_sd_unit) && ~isempty(obj.waveform_sd) && isobject(obj.waveform_sd) && isprop(obj.waveform_sd, 'unit') && ~isempty(obj.waveform_sd.unit)
obj.waveform_sd_unit = obj.waveform_sd.unit;
end
if ~isempty(obj.waveform_sd) && ~isa(obj.waveform_sd, 'types.untyped.SoftLink') && ~isa(obj.waveform_sd, 'types.untyped.ExternalLink') && ~isempty(obj.waveform_sd_unit)
writer.writeAttribute([fullpath '/waveform_sd/unit'], obj.waveform_sd_unit);
end
Expand All @@ -436,9 +430,6 @@ function postset_waveforms_sampling_rate(obj)
if ~isempty(obj.waveforms) && ~isa(obj.waveforms, 'types.untyped.SoftLink') && ~isa(obj.waveforms, 'types.untyped.ExternalLink') && ~isempty(obj.waveforms_sampling_rate)
writer.writeAttribute([fullpath '/waveforms/sampling_rate'], obj.waveforms_sampling_rate);
end
if isempty(obj.waveforms_unit) && ~isempty(obj.waveforms) && isobject(obj.waveforms) && isprop(obj.waveforms, 'unit') && ~isempty(obj.waveforms.unit)
obj.waveforms_unit = obj.waveforms.unit;
end
if ~isempty(obj.waveforms) && ~isa(obj.waveforms, 'types.untyped.SoftLink') && ~isa(obj.waveforms, 'types.untyped.ExternalLink') && ~isempty(obj.waveforms_unit)
writer.writeAttribute([fullpath '/waveforms/unit'], obj.waveforms_unit);
end
Expand Down
11 changes: 0 additions & 11 deletions +types/+hdmf_common/VectorData.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
% data, description


% HIDDEN READONLY PROPERTIES
properties(Hidden, SetAccess = protected)
unit = "volts"; % (char) NOTE: this is a special value for compatibility with the Units table and is only written to file when detected to be in that specific HDF5 Group. The value must be 'volts'
end
% HIDDEN PROPERTIES
properties(Hidden)
resolution; % (double) NOTE: this is a special value for compatibility with the Units table and is only written to file when detected to be in that specific HDF5 Group. The smallest possible difference between two spike times. Usually 1 divided by the acquisition sampling rate from which spike times were extracted, but could be larger if the acquisition time series was downsampled or smaller if the acquisition time series was smoothed/interpolated and it is possible for the spike time to be between samples.
Expand Down Expand Up @@ -40,7 +36,6 @@
% Output Arguments:
% - vectorData (types.hdmf_common.VectorData) - A VectorData object

varargin = [{'unit' 'volts'} varargin];
obj = obj@types.hdmf_common.Data(varargin{:});


Expand All @@ -51,12 +46,10 @@
addParameter(p, 'description',[]);
addParameter(p, 'resolution',[]);
addParameter(p, 'sampling_rate',[]);
addParameter(p, 'unit',[]);
misc.parseSkipInvalidName(p, varargin);
obj.description = p.Results.description;
obj.resolution = p.Results.resolution;
obj.sampling_rate = p.Results.sampling_rate;
obj.unit = p.Results.unit;

% Only execute validation/setup code when called directly in this class's
% constructor, not when invoked through superclass constructor chain
Expand Down Expand Up @@ -107,10 +100,6 @@
if ~isempty(obj.sampling_rate) && any(endsWith(fullpath, validDataSamplingPaths))
writer.writeAttribute([fullpath '/sampling_rate'], obj.sampling_rate);
end
validUnitPaths = strcat('units/', {'waveform_mean', 'waveform_sd', 'waveforms'});
if ~isempty(obj.unit) && any(endsWith(fullpath, validUnitPaths))
writer.writeAttribute([fullpath '/unit'], obj.unit);
end
end
end

Expand Down