Skip to content

Commit cb69eb9

Browse files
committed
[c++/m] Add nix.MultiTag retrieveFeatureData func
1 parent f43ab97 commit cb69eb9

File tree

5 files changed

+110
-0
lines changed

5 files changed

+110
-0
lines changed

+nix/MultiTag.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@
118118
'MultiTag::openFeatureIdx', idx, @nix.Feature);
119119
end;
120120

121+
function data = retrieve_feature_data(obj, pos_idx, id_or_name)
122+
tmp = nix_mx('MultiTag::featureRetrieveData', ...
123+
obj.nix_handle, pos_idx, id_or_name);
124+
125+
% data must agree with file & dimensions; see mkarray.cc(42)
126+
data = permute(tmp, length(size(tmp)):-1:1);
127+
end;
128+
121129
function data = retrieve_feature_data_idx(obj, pos_idx, feat_idx)
122130
tmp = nix_mx('MultiTag::featureRetrieveDataIdx', ...
123131
obj.nix_handle, pos_idx, feat_idx);

nix_mx.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ void mexFunction(int nlhs,
379379
methods->add("MultiTag::featuresFiltered", nixmultitag::featuresFiltered);
380380
methods->add("MultiTag::retrieveData", nixmultitag::retrieveData);
381381
methods->add("MultiTag::retrieveDataIdx", nixmultitag::retrieveDataIdx);
382+
methods->add("MultiTag::featureRetrieveData", nixmultitag::retrieveFeatureData);
382383
methods->add("MultiTag::featureRetrieveDataIdx", nixmultitag::retrieveFeatureDataIdx);
383384

384385
classdef<nix::Section>("Section", methods)

src/nixmultitag.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ namespace nixmultitag {
135135
output.set(0, data);
136136
}
137137

138+
void retrieveFeatureData(const extractor &input, infusor &output) {
139+
nix::MultiTag currObj = input.entity<nix::MultiTag>(1);
140+
size_t pos_idx = (size_t)input.num<double>(2);
141+
std::string name_id = input.str(3);
142+
143+
mxArray *data = make_mx_array_from_ds(currObj.retrieveFeatureData(pos_idx, name_id));
144+
output.set(0, data);
145+
}
146+
138147
void retrieveFeatureDataIdx(const extractor &input, infusor &output) {
139148
nix::MultiTag currObj = input.entity<nix::MultiTag>(1);
140149
size_t pos_idx = (size_t)input.num<double>(2);

src/nixmultitag.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ namespace nixmultitag {
4545

4646
void retrieveDataIdx(const extractor &input, infusor &output);
4747

48+
void retrieveFeatureData(const extractor &input, infusor &output);
49+
4850
void retrieveFeatureDataIdx(const extractor &input, infusor &output);
4951

5052
} // namespace nixmultitag

tests/TestMultiTag.m

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
funcs{end+1} = @test_open_metadata;
4343
funcs{end+1} = @test_retrieve_data;
4444
funcs{end+1} = @test_retrieve_data_idx;
45+
funcs{end+1} = @test_retrieve_feature_data;
4546
funcs{end+1} = @test_retrieve_feature_data_idx;
4647
funcs{end+1} = @test_set_units;
4748
funcs{end+1} = @test_attrs;
@@ -767,6 +768,95 @@
767768
assert(isequal(t.retrieve_data_idx(2, 1), raw2(1:2, 3:6)), 'Retrieve pos 3, ref 2 fail');
768769
end
769770

771+
%% Test: Retrieve feature data by id or name
772+
function [] = test_retrieve_feature_data( varargin )
773+
f = nix.File(fullfile(pwd, 'tests', 'testRW.h5'), nix.FileMode.Overwrite);
774+
b = f.create_block('testBlock', 'nixBlock');
775+
776+
% create feature data arrays
777+
raw_feat1 = [11 12 13 14 15 16 17 18];
778+
da_feat1 = b.create_data_array_from_data('feature1', 'nixDataArray', raw_feat1);
779+
da_feat1.append_sampled_dimension(1);
780+
781+
raw_feat2 = [21 22 23 24 25 26 27 28];
782+
da_feat2 = b.create_data_array_from_data('feature2', 'nixDataArray', raw_feat2);
783+
da_feat2.append_sampled_dimension(1);
784+
785+
% create referenced data array
786+
raw_feat3 = [31 32 33 34 35 36 37 38];
787+
da_feat3 = b.create_data_array_from_data('reference', 'nixDataArray', raw_feat3);
788+
da_feat3.append_sampled_dimension(1);
789+
790+
% create position, extents DA and multi tag
791+
pos = [0; 3; 5];
792+
ext = [1; 1; 3];
793+
794+
da_pos = b.create_data_array_from_data('positions', 'nixDataArray', pos);
795+
da_ext = b.create_data_array_from_data('extents', 'nixDataArray', ext);
796+
797+
da_pos.append_sampled_dimension(0);
798+
da_ext.append_sampled_dimension(0);
799+
800+
t = b.create_multi_tag('testMultiTag', 'nixMultiTag', da_pos);
801+
t.set_extents(da_ext);
802+
803+
% add feature data_arrays
804+
t.add_feature(da_feat1, nix.LinkType.Untagged);
805+
t.add_feature(da_feat2, nix.LinkType.Tagged);
806+
t.add_feature(da_feat3, nix.LinkType.Indexed);
807+
808+
% test invalid position idx
809+
try
810+
t.retrieve_feature_data(100, '');
811+
catch ME
812+
assert(isempty(strfind(ME.message, 'ounds of positions or extents')), ...
813+
'Invalid position index failed');
814+
end
815+
assert(exist('ME') == 1, 'Invalid position index fail, error not raised');
816+
clear ME;
817+
818+
% test invalid name or id
819+
try
820+
t.retrieve_feature_data(0, 'I do not exist');
821+
catch ME
822+
assert(~isempty(strfind(ME.message, 'no Feature with the specified name or id')), ...
823+
'Invalid reference name failed');
824+
end
825+
assert(exist('ME') == 1, 'Invalid reference name fail, error not raised');
826+
clear ME;
827+
828+
% test untagged ignores position and returns full data
829+
retData = t.retrieve_feature_data(100, da_feat1.name);
830+
assert(isequal(raw_feat1, retData), 'Untagged fail');
831+
832+
% test tagged properly applies position and extents
833+
retData = t.retrieve_feature_data(0, da_feat2.id);
834+
assert(isequal(retData, [21]), 'Tagged pos 1 fail');
835+
836+
retData = t.retrieve_feature_data(1, da_feat2.name);
837+
assert(isequal(retData, [24]), 'Tagged pos 2 fail');
838+
839+
retData = t.retrieve_feature_data(2, da_feat2.id);
840+
assert(isequal(retData, [26, 27, 28]), 'Tagged pos 3 fail');
841+
842+
% test indexed returns first and last index value
843+
retData = t.retrieve_feature_data(0, da_feat3.id);
844+
assert(isequal(retData, raw_feat3(1)), 'Indexed first pos fail');
845+
846+
retData = t.retrieve_feature_data(7, da_feat3.name);
847+
assert(isequal(retData, raw_feat3(end)), 'Indexed last pos fail');
848+
849+
% test indexed fail when accessing position > length of referenced array
850+
try
851+
t.retrieve_feature_data(size(raw_feat3, 2) + 1, da_feat3.id);
852+
catch ME
853+
assert(~isempty(strfind(ME.message, 'than the data stored in the feature')), ...
854+
'Indexed out of length fail');
855+
end
856+
assert(exist('ME') == 1, 'Indexed out of length fail, error not raised');
857+
clear ME;
858+
end
859+
770860
%% Test: Retrieve feature data
771861
function [] = test_retrieve_feature_data_idx( varargin )
772862
f = nix.File(fullfile(pwd, 'tests', 'testRW.h5'), nix.FileMode.Overwrite);

0 commit comments

Comments
 (0)