Skip to content

Commit 291394e

Browse files
committed
Merge branch 'release/v0.1.0'
2 parents 4b5c2b8 + 4fd0b34 commit 291394e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2216
-2
lines changed

+SDF/+NDTable/interpolate.m

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
function y = interpolate(points, data, scales, varargin)
2+
3+
assert(mod(numel(varargin), 2) == 0, 'Wrong number of arguments')
4+
5+
interp_method = 2;
6+
extrap_method = 2;
7+
8+
for i = 1:2:numel(varargin)
9+
10+
name = varargin{i};
11+
value = varargin{i + 1};
12+
13+
if strcmpi(name, 'InterpMethod')
14+
15+
if strcmpi(value, 'Hold')
16+
interp_method = 1;
17+
elseif strcmpi(value, 'Nearest')
18+
interp_method = 2;
19+
elseif strcmpi(value, 'Linear')
20+
interp_method = 3;
21+
elseif strcmpi(value, 'Akima')
22+
interp_method = 4;
23+
elseif strcmpi(value, 'FritschButland')
24+
interp_method = 5;
25+
elseif strcmpi(value, 'Steffen')
26+
interp_method = 6;
27+
else
28+
error('InterpMethod must be one of Hold, Nearest, Linear, Akima, FritschButland or Steffen')
29+
end
30+
31+
elseif strcmpi(name, 'ExtrapMethod')
32+
33+
if strcmpi(value, 'Hold')
34+
extrap_method = 1;
35+
elseif strcmpi(value, 'Linear')
36+
extrap_method = 2;
37+
elseif strcmpi(value, 'None')
38+
extrap_method = 3;
39+
else
40+
error('ExtrapMethod must be one of Hold, Linear or None')
41+
end
42+
43+
else
44+
45+
error(['Unknown key: ' name])
46+
47+
end
48+
49+
50+
end
51+
52+
% convert from column-major (FORTRAN) to row-major (C) order
53+
order = fliplr(1:ndims(data));
54+
data = permute(data, order);
55+
56+
y = mex_ndtable(fliplr(points)', data, scales, interp_method, extrap_method);
57+
58+
end

+SDF/Dataset.m

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
% Copyright (c) 2016 Dassault Systemes. All rights reserved.
2+
3+
classdef Dataset < handle
4+
5+
properties
6+
name = ''
7+
comment = ''
8+
attributes = struct([])
9+
data = []
10+
display_name = ''
11+
relative_quantity = false
12+
unit = ''
13+
display_unit = ''
14+
is_scale = false
15+
scales = SDF.Dataset.empty
16+
end
17+
18+
properties (Dependent)
19+
rank
20+
end
21+
22+
methods
23+
24+
function self = Dataset()
25+
self.attributes = struct();
26+
self.relative_quantity = false;
27+
self.is_scale = 0;
28+
end
29+
30+
function value = get.rank(obj)
31+
s = size(obj.data);
32+
nd = ndims(obj.data);
33+
34+
if nd > 2
35+
value = nd;
36+
elseif s(1) <= 1 && s(2) <= 1
37+
value = 0;
38+
elseif s(1) == 1 || s(2) == 1
39+
value = 1;
40+
else
41+
value = nd;
42+
end
43+
end
44+
45+
end
46+
47+
end

+SDF/Group.m

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
% Copyright (c) 2016 Dassault Systemes. All rights reserved.
2+
3+
classdef Group < handle
4+
5+
properties
6+
name = ''
7+
comment = ''
8+
attributes = struct([])
9+
datasets = SDF.Dataset.empty
10+
groups = SDF.Group.empty
11+
end
12+
13+
methods
14+
15+
function object = find_object(self, object_name)
16+
17+
object = [];
18+
19+
segments = strsplit(object_name, '/');
20+
21+
first = '';
22+
23+
while isempty(first) && ~isempty(segments)
24+
first = segments{1};
25+
segments = segments(2:end);
26+
end
27+
28+
if isempty(first)
29+
% path is empty
30+
return
31+
end
32+
33+
% search the datasets
34+
for i = 1:numel(self.datasets)
35+
dataset = self.datasets(i);
36+
if strcmp(dataset.name, first)
37+
object = dataset;
38+
return
39+
end
40+
end
41+
42+
% search the groups
43+
for i = 1:numel(self.groups)
44+
group = self.groups(i);
45+
if strcmp(group.name, first)
46+
if isempty(segments)
47+
object = group;
48+
else
49+
% continue the search
50+
path = strjoin(segments, '/');
51+
object = group.find_object(path);
52+
end
53+
end
54+
end
55+
56+
end
57+
58+
end
59+
60+
end

+SDF/load.m

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
%SDF.LOAD Load a dataset from an SDF file
2+
%
3+
% g = SDF.load(FILENAME) loads the whole file and returns an SDF.Group
4+
%
5+
% obj = SDF.load(FILENAME, OBJECT_NAME) loads an object from an SDF file
6+
% and returns an SDF.Group or SDF.Dataset
7+
%
8+
% ds = SDF.load(FILENAME, DATASET_NAME, UNIT) loads a dataset, asserts
9+
% the unit and returns an SDF.Dataset
10+
%
11+
% ds = SDF.load(FILENAME, DATASET_NAME, UNIT, SCALE_UNITS) loads a
12+
% dataset, asserts the unit, dimensions, scale units and returns an SDF.Dataset
13+
%
14+
% Example:
15+
%
16+
% ds = SDF.load('data.sdf', '/signals/v') % load the dataset 'v' in group 'singals
17+
% ds = SDF.load('data.sdf', '/signals/v', 'V') % assert the unit 'V'
18+
% ds = SDF.load('data.sdf', '/signals/v', 'V', {'s'}) % assert the unit 's' of the scale for dimension 1
19+
% ds = SDF.load('data.sdf', '/signals/v', '', {''}) % assert that /v is a 1-d dataset
20+
21+
function object = load(filename, varargin)
22+
23+
% check if the file exists
24+
assert(exist(filename, 'file') == 2, ['The file ''' filename ''' does not exist'])
25+
26+
[~, ~, ext] = fileparts(filename);
27+
28+
object_name = '/';
29+
30+
if numel(varargin) >= 1
31+
object_name = varargin{1};
32+
end
33+
34+
if strcmp(ext, '.sdf')
35+
object = read_hdf5(filename, object_name);
36+
elseif strcmp(ext, '.mat')
37+
object = read_dsres(filename, object_name);
38+
else
39+
error('Unknown file format')
40+
end
41+
42+
if numel(varargin) >= 2
43+
% check the unit
44+
assert(isa(object, 'SDF.Dataset'), ['Unit was provided but ' object_name ' is not a dataset.'])
45+
unit = varargin{2};
46+
if ~isempty(unit)
47+
assert(strcmp(object.unit, unit), ['Dataset ' object_name ' has the wrong unit. Expected ''' unit ''' but was ''' object.unit '''.'])
48+
end
49+
end
50+
51+
if numel(varargin) >= 3
52+
53+
% check the rank
54+
scale_units = varargin{3};
55+
rank = numel(scale_units);
56+
assert(object.rank == rank, ['Dataset has the wrong rank. Expected ' num2str(rank) ' but was ' num2str(object.rank) '.'])
57+
58+
% check the scale units
59+
for i = 1:numel(scale_units)
60+
scale_unit = scale_units{i};
61+
if ~isempty(scale_unit)
62+
scale = object.scales(i);
63+
assert(strcmp(scale.unit, scale_unit), ['The scale for dimension ' num2str(i) ' has the wrong unit. Expected ''' scale_unit ''' but was ''' scale.unit '''.'])
64+
end
65+
end
66+
67+
end

+SDF/private/read_dsres.m

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
function object = read_dsres(filename, object_name)
2+
3+
mat = load(filename);
4+
5+
% get the arrays
6+
file_info = mat.Aclass;
7+
8+
if strcmp(file_info(2,1:3), '1.1')
9+
if strcmp(file_info(4,1:8), 'binTrans')
10+
info = mat.dataInfo;
11+
desc = mat.description';
12+
cons = mat.data_1';
13+
vars = mat.data_2';
14+
names = mat.name';
15+
elseif strcmp(file_info(4,1:9), 'binNormal')
16+
info = mat.dataInfo';
17+
desc = mat.description;
18+
cons = mat.data_1;
19+
vars = mat.data_2;
20+
names = mat.name;
21+
else
22+
error('Format not supported')
23+
end
24+
elseif strcmp(file_info(2,1:3), '1.0')
25+
26+
names = mat.names;
27+
vars = mat.data;
28+
n = size(vars, 2);
29+
desc = char(zeros(n,1));
30+
info = [ones(n,1).*2, [1:n]']';
31+
32+
else
33+
error('Format not supported')
34+
end
35+
36+
% remove the string terminators so strtrim() works correctly
37+
names(names == 0) = ' ';
38+
desc(desc == 0) = ' ';
39+
40+
n = size(info, 2);
41+
42+
root = SDF.Group();
43+
44+
ds_time = SDF.Dataset();
45+
ds_time.name = strtrim(names(1, :));
46+
ds_time.comment = strtrim(desc(1, :));
47+
ds_time.unit = 's';
48+
ds_time.data = vars(:, 1);
49+
ds_time.is_scale = true;
50+
51+
root.datasets(end+1) = ds_time;
52+
53+
for i = 2:n
54+
55+
ds = SDF.Dataset();
56+
57+
d = info(1, i); % variability (constant=1, variable=2)
58+
x = info(2, i);
59+
c = abs(x); % colum
60+
s = sign(x); % sign
61+
62+
path = strtrim(names(i, :));
63+
64+
path_elements = strsplit(path, '.');
65+
66+
parent_group = root;
67+
68+
for j = 1:numel(path_elements)-1
69+
path_element = path_elements{j};
70+
pg = [];
71+
72+
for k = 1:numel(parent_group.groups)
73+
if strcmp(parent_group.groups(k).name, path_element)
74+
pg = parent_group.groups(k);
75+
break
76+
end
77+
end
78+
79+
if isempty(pg)
80+
pg = SDF.Group();
81+
pg.name = path_element;
82+
parent_group.groups(end+1) = pg;
83+
end
84+
85+
parent_group = pg;
86+
end
87+
88+
comment = strtrim(desc(i, :));
89+
last = find(comment == '[', 1, 'last');
90+
91+
if d == 1
92+
data = cons(1, c);
93+
else
94+
data = vars(:, c);
95+
ds.scales = ds_time;
96+
end
97+
98+
unit = '';
99+
display_unit = '';
100+
101+
if ~isempty(comment) && comment(end) == ']' && last
102+
type_info = comment(last+1:end-1);
103+
comment = comment(1:last-1);
104+
elements = strsplit(type_info, ':#');
105+
for j = 1:numel(elements)
106+
element = elements{j};
107+
if strcmp(element, '(type=Integer)')
108+
% change type
109+
data = int32(data);
110+
elseif strcmp(element, '(type=Boolean)')
111+
% change type
112+
data = logical(data);
113+
elseif ~isempty(element)
114+
unit = element;
115+
end
116+
end
117+
end
118+
119+
j = find(unit == '|');
120+
121+
if j
122+
display_unit = unit(j+1:end);
123+
unit = unit(1:j-1);
124+
end
125+
126+
if s < 0
127+
data = -data;
128+
end
129+
130+
ds.name = path_elements{end};
131+
ds.comment = strtrim(comment);
132+
ds.unit = unit;
133+
ds.display_unit = display_unit;
134+
ds.data = data;
135+
136+
parent_group.datasets(end+1) = ds;
137+
138+
end
139+
140+
if strcmp(object_name, '/')
141+
object = root;
142+
else
143+
object = root.find_object(object_name);
144+
end
145+
146+
end

0 commit comments

Comments
 (0)