Skip to content

Commit 923401c

Browse files
committed
[c++/m] Refactor nix.MultiTag retrieveFeatureData
- rename existing function to retrieveFeatureDataIdx - remove index manipulation on Matlab side - rewrite existing test
1 parent c28a20a commit 923401c

File tree

5 files changed

+103
-24
lines changed

5 files changed

+103
-24
lines changed

+nix/MultiTag.m

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,11 @@
111111
'MultiTag::openFeatureIdx', idx, @nix.Feature);
112112
end;
113113

114-
function data = retrieve_feature_data(obj, pos_index, fea_index)
115-
% convert Matlab-like to C-like index
116-
assert(pos_index > 0, 'Position index must be positive');
117-
assert(fea_index > 0, 'Feature index must be positive');
118-
tmp = nix_mx('MultiTag::featureRetrieveData', obj.nix_handle, ...
119-
pos_index - 1, fea_index - 1);
114+
function data = retrieve_feature_data_idx(obj, pos_idx, feat_idx)
115+
tmp = nix_mx('MultiTag::featureRetrieveDataIdx', ...
116+
obj.nix_handle, pos_idx, feat_idx);
120117

121-
% data must agree with file & dimensions
122-
% see mkarray.cc(42)
118+
% data must agree with file & dimensions; see mkarray.cc(42)
123119
data = permute(tmp, length(size(tmp)):-1:1);
124120
end;
125121

nix_mx.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ void mexFunction(int nlhs,
364364
.reg("sourceCount", GETTER(nix::ndsize_t, nix::MultiTag, sourceCount))
365365
.reg("referenceCount", GETTER(nix::ndsize_t, nix::MultiTag, referenceCount))
366366
.reg("featureCount", GETTER(nix::ndsize_t, nix::MultiTag, featureCount));
367-
methods->add("MultiTag::featureRetrieveData", nixmultitag::retrieveFeatureData);
368367
methods->add("MultiTag::addReference", nixmultitag::addReference);
369368
methods->add("MultiTag::addReferences", nixmultitag::addReferences);
370369
methods->add("MultiTag::addSource", nixmultitag::addSource);
@@ -379,6 +378,7 @@ void mexFunction(int nlhs,
379378
methods->add("MultiTag::referencesFiltered", nixmultitag::referencesFiltered);
380379
methods->add("MultiTag::featuresFiltered", nixmultitag::featuresFiltered);
381380
methods->add("MultiTag::retrieveDataIdx", nixmultitag::retrieveDataIdx);
381+
methods->add("MultiTag::featureRetrieveDataIdx", nixmultitag::retrieveFeatureDataIdx);
382382

383383
classdef<nix::Section>("Section", methods)
384384
.desc(&nixsection::describe)

src/nixmultitag.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,6 @@ namespace nixmultitag {
6161
output.set(0, handle(newFeat));
6262
}
6363

64-
void retrieveFeatureData(const extractor &input, infusor &output) {
65-
nix::MultiTag currObj = input.entity<nix::MultiTag>(1);
66-
double p_index = input.num<double>(2);
67-
double f_index = input.num<double>(3);
68-
69-
mxArray *data = make_mx_array_from_ds(currObj.retrieveFeatureData(p_index, f_index));
70-
output.set(0, data);
71-
}
72-
7364
void addPositions(const extractor &input, infusor &output) {
7465
nix::MultiTag currObj = input.entity<nix::MultiTag>(1);
7566
currObj.positions(input.str(2));
@@ -135,4 +126,13 @@ namespace nixmultitag {
135126
output.set(0, data);
136127
}
137128

129+
void retrieveFeatureDataIdx(const extractor &input, infusor &output) {
130+
nix::MultiTag currObj = input.entity<nix::MultiTag>(1);
131+
size_t pos_idx = (size_t)input.num<double>(2);
132+
size_t ref_idx = (size_t)input.num<double>(3);
133+
134+
mxArray *data = make_mx_array_from_ds(currObj.retrieveFeatureData(pos_idx, ref_idx));
135+
output.set(0, data);
136+
}
137+
138138
} // namespace nixmultitag

src/nixmultitag.h

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

2626
void createFeature(const extractor &input, infusor &output);
2727

28-
void retrieveFeatureData(const extractor &input, infusor &output);
29-
3028
void addPositions(const extractor &input, infusor &output);
3129

3230
void openReferenceIdx(const extractor &input, infusor &output);
@@ -45,6 +43,8 @@ namespace nixmultitag {
4543

4644
void retrieveDataIdx(const extractor &input, infusor &output);
4745

46+
void retrieveFeatureDataIdx(const extractor &input, infusor &output);
47+
4848
} // namespace nixmultitag
4949

5050
#endif

tests/TestMultiTag.m

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
funcs{end+1} = @test_set_metadata;
4242
funcs{end+1} = @test_open_metadata;
4343
funcs{end+1} = @test_retrieve_data_idx;
44-
funcs{end+1} = @test_retrieve_feature_data;
44+
funcs{end+1} = @test_retrieve_feature_data_idx;
4545
funcs{end+1} = @test_set_units;
4646
funcs{end+1} = @test_attrs;
4747
funcs{end+1} = @test_compare;
@@ -704,9 +704,92 @@
704704
end
705705

706706
%% Test: Retrieve feature data
707-
function [] = test_retrieve_feature_data( varargin )
708-
% TODO
709-
disp('Test MultiTag: retrieve feature ... TODO (proper testfile)');
707+
function [] = test_retrieve_feature_data_idx( varargin )
708+
f = nix.File(fullfile(pwd, 'tests', 'testRW.h5'), nix.FileMode.Overwrite);
709+
b = f.create_block('testBlock', 'nixBlock');
710+
711+
% create feature data arrays
712+
raw_feat1 = [11 12 13 14 15 16 17 18];
713+
da_feat1 = b.create_data_array_from_data('feature1', 'nixDataArray', raw_feat1);
714+
da_feat1.append_sampled_dimension(1);
715+
716+
raw_feat2 = [21 22 23 24 25 26 27 28];
717+
da_feat2 = b.create_data_array_from_data('feature2', 'nixDataArray', raw_feat2);
718+
da_feat2.append_sampled_dimension(1);
719+
720+
% create referenced data array
721+
raw_feat3 = [31 32 33 34 35 36 37 38];
722+
da_feat3 = b.create_data_array_from_data('reference', 'nixDataArray', raw_feat3);
723+
da_feat3.append_sampled_dimension(1);
724+
725+
% create position, extents DA and multi tag
726+
pos = [0; 3; 5];
727+
ext = [1; 1; 3];
728+
729+
da_pos = b.create_data_array_from_data('positions', 'nixDataArray', pos);
730+
da_ext = b.create_data_array_from_data('extents', 'nixDataArray', ext);
731+
732+
da_pos.append_sampled_dimension(0);
733+
da_ext.append_sampled_dimension(0);
734+
735+
t = b.create_multi_tag('testMultiTag', 'nixMultiTag', da_pos);
736+
t.set_extents(da_ext);
737+
738+
% add feature data_arrays
739+
t.add_feature(da_feat1, nix.LinkType.Untagged);
740+
t.add_feature(da_feat2, nix.LinkType.Tagged);
741+
t.add_feature(da_feat3, nix.LinkType.Indexed);
742+
743+
% test invalid position idx
744+
try
745+
t.retrieve_feature_data_idx(100, 1);
746+
catch ME
747+
assert(isempty(strfind(ME.message, 'ounds of positions or extents')), ...
748+
'Invalid position index failed');
749+
end
750+
assert(exist('ME') == 1, 'Invalid position index fail, error not raised');
751+
clear ME;
752+
753+
% test invalid feature idx
754+
try
755+
t.retrieve_feature_data_idx(0, 100);
756+
catch ME
757+
assert(~isempty(strfind(ME.message, 'out of bounds')), ...
758+
'Invalid reference index failed');
759+
end
760+
assert(exist('ME') == 1, 'Invalid reference index fail, error not raised');
761+
clear ME;
762+
763+
% test untagged ignores position and returns full data
764+
retData = t.retrieve_feature_data_idx(100, 0);
765+
assert(isequal(raw_feat1, retData), 'Untagged fail');
766+
767+
% test tagged properly applies position and extents
768+
retData = t.retrieve_feature_data_idx(0, 1);
769+
assert(isequal(retData, [21]), 'Tagged pos 1 fail');
770+
771+
retData = t.retrieve_feature_data_idx(1, 1);
772+
assert(isequal(retData, [24]), 'Tagged pos 2 fail');
773+
774+
retData = t.retrieve_feature_data_idx(2, 1);
775+
assert(isequal(retData, [26, 27, 28]), 'Tagged pos 3 fail');
776+
777+
% test indexed returns first and last index value
778+
retData = t.retrieve_feature_data_idx(0, 2);
779+
assert(isequal(retData, raw_feat3(1)), 'Indexed first pos fail');
780+
781+
retData = t.retrieve_feature_data_idx(7, 2);
782+
assert(isequal(retData, raw_feat3(end)), 'Indexed last pos fail');
783+
784+
% test indexed fail when accessing position > length of referenced array
785+
try
786+
t.retrieve_feature_data_idx(size(raw_feat3, 2) + 1, 2);
787+
catch ME
788+
assert(~isempty(strfind(ME.message, 'than the data stored in the feature')), ...
789+
'Indexed out of length fail');
790+
end
791+
assert(exist('ME') == 1, 'Indexed out of length fail, error not raised');
792+
clear ME;
710793
end
711794

712795
%% Test: nix.MultiTag has feature by ID

0 commit comments

Comments
 (0)