Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add groundwork for data flag & outlier marking #22

Merged
merged 49 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3d3da83
Start adopting new GearKit dataPool storage
davidclemens Dec 8, 2020
391f7b0
Fix minor bugs
davidclemens Dec 8, 2020
5f1a9ba
Add deviceDomain
davidclemens Dec 9, 2020
bc7a403
Add new findVariable method
davidclemens Dec 10, 2020
742d18a
Add ability to configure measurementDevices
davidclemens Dec 10, 2020
e39cb4a
Minor changes
davidclemens Dec 14, 2020
3e0c882
Add duration variables
davidclemens Dec 14, 2020
720bd07
Minor changes
davidclemens Dec 14, 2020
9c244db
Make metadata output consistent
davidclemens Dec 14, 2020
4fd364b
Add new calibration method
davidclemens Dec 14, 2020
c453465
Add new unit test
davidclemens Dec 14, 2020
de0cacd
Initial outlier marking implementation
davidclemens Dec 14, 2020
a5871a3
New validFlag class
davidclemens Jan 5, 2021
da782e4
New dataFlag & sparseBitmask class
davidclemens Jan 5, 2021
7491dd7
Overload builtin methods for sparseBitmask
davidclemens Jan 6, 2021
51ec828
Minor changes
davidclemens Jan 6, 2021
4e169fc
Add data flags to outlier marking
davidclemens Jan 6, 2021
1de9c0d
Switch to using arrayhom
davidclemens Jan 7, 2021
c485cb2
Overload builtin methods & minor fixes
davidclemens Jan 7, 2021
a19e5f4
Add data flags to fetch data methods
davidclemens Jan 7, 2021
e1b4564
Add setFlag method to dataPool
davidclemens Jan 12, 2021
2e38d28
Add isFlag method to dataFlag
davidclemens Jan 12, 2021
fd15e5e
Refactor setBit algorithm to increase speed
davidclemens Jan 12, 2021
89817fe
Add method abbreviation2devicedomain to deviceDomain
davidclemens Jan 12, 2021
60bb10a
Fix bug
davidclemens Jan 12, 2021
cf17142
Fix bug
davidclemens Jan 12, 2021
0c42c34
Add missing deviceDomain to analytical samples
davidclemens Jan 12, 2021
6cd541b
Fix bug
davidclemens Jan 12, 2021
a9718cb
Improve flag setting & other fixes
davidclemens Jan 12, 2021
df46152
Add options & grey out set dataFlags
davidclemens Jan 12, 2021
a4d3888
Track .png files using git lfs
davidclemens Jan 12, 2021
1d9f3e7
Change tests to use shared fixture
davidclemens Jan 14, 2021
49a89c9
Add tests
davidclemens Jan 14, 2021
43014f7
Fix bugs
davidclemens Jan 14, 2021
59930af
Minor changes
davidclemens Jan 14, 2021
c383a41
Merge development into refactor-outlier-marking
davidclemens Jan 18, 2021
e8f67f1
Merge development
davidclemens Jan 19, 2021
a8d05cf
Merge development
davidclemens Jan 19, 2021
daa552b
Fixed test failures
davidclemens Jan 20, 2021
f26cdb4
Add isequal method to dataPool
davidclemens Jan 20, 2021
0e152c2
Implement gearDeployment save/load interface
davidclemens Jan 20, 2021
a1384f6
Add initial unit test to save/load interface
davidclemens Jan 20, 2021
69b21be
Restructure save/load interface
davidclemens Jan 21, 2021
7da58e7
Minor changes
davidclemens Jan 21, 2021
27aaab4
Add automatic saving to markQualityFlags
davidclemens Jan 21, 2021
5b4c4d1
Overload ==/eq for sparseBitmask & dataFlag
davidclemens Jan 21, 2021
c137cc1
Add optional color input to dataBrushWindow constructor
davidclemens Jan 21, 2021
0aad8ed
Improve markQualtiyFlag
davidclemens Jan 21, 2021
6d3425f
Improve plot for gearDeployment
davidclemens Jan 21, 2021
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
23 changes: 23 additions & 0 deletions +DataKit/+Metadata/+validators/@validFlag/listAllValidFlagInfo.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function tbl = listAllValidFlagInfo()


flagList = enumeration('DataKit.Metadata.validators.validFlag');
flagProps = properties('DataKit.Metadata.validators.validFlag');

propClass = cellfun(@class,cellfun(@(p) flagList(1).(p),flagProps,'un',0),'un',0);
tblStruct = struct();
for prop = 1:numel(flagProps)
switch propClass{prop}
case 'char'
column = {flagList(:).(flagProps{prop})}';
case {'single','double','int8','int16','int32','uint8','uint16','uint32','uint64'}
column = cat(1,flagList(:).(flagProps{prop}));
otherwise
error('%s is not implemented yet.',propClass{prop})
end

tblStruct.(flagProps{prop}) = column;
end
tbl = struct2table(tblStruct);
tbl.Flag = flagList;
end
37 changes: 37 additions & 0 deletions +DataKit/+Metadata/+validators/@validFlag/validFlag.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
classdef validFlag
enumeration
% quality flag id description
undefined (0, '')
OutOfCalibrationRange (1, 'Value out of calibration range')
BelowDetectionLimit (2, 'Value below the detection limit')
MarkedRejected (3, 'Value was manually rejected')
end
properties
Id uint8
Description char
end
properties (Dependent)
Bitmask uint64
end
methods
function obj = validFlag(id,description,varargin)
obj.Id = id;
obj.Description = description;
end
end

methods (Static)
tbl = listAllValidFlagInfo()
end

% get methods
methods
function Bitmask = get.Bitmask(obj)
if obj.Id == 0
Bitmask = 0;
else
Bitmask = bitset(0,obj.Id,1);
end
end
end
end
19 changes: 19 additions & 0 deletions +DataKit/+Metadata/@dataFlag/cat.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function obj = cat(dim,varargin)

import DataKit.Metadata.dataFlag

isaDataFlag = cellfun(@(in) isa(in,'DataKit.Metadata.dataFlag'),varargin);
if ~all(isaDataFlag)
error('DataKit:Metadata:dataFlag:cat:invalidInputType',...
'All inputs must be data flags')
end

% extract all bitmasks
bitmasks = cellfun(@(in) in.Bitmask,varargin,'un',0);

% concatenate the bitmask
bitmask = cat(dim,bitmasks{:});

% create new sparse bitmask object
obj = dataFlag(bitmask);
end
57 changes: 57 additions & 0 deletions +DataKit/+Metadata/@dataFlag/dataFlag.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
classdef dataFlag < DataKit.Metadata.sparseBitmask

methods
function obj = dataFlag(varargin)

obj = [email protected](varargin{:});

% validate input ids
switch nargin
case 0
return
case 1
bitmasks = varargin{1}(:);
isNotZero = bitmasks ~= 0;
bitmasks = full(bitmasks(isNotZero));
n = sum(isNotZero);
bitmask = zeros(n,52);
for ii = 1:n
bitmask(ii,:) = bitget(bitmasks(ii),1:52);
end
[~,flagId] = find(bitmask);
case 2
flagId = 0;
case 3
flagId = varargin{3}(:);
case 5
flagId = varargin{3}(:);
otherwise
error('DataKit:Metadata:dataFlag:invalidNumberOfInputs',...
'Invalid number of inputs.')
end
isValid = DataKit.Metadata.dataFlag.validateId(flagId);
if any(~isValid)
error('DataKit:Metadata:dataFlag:dataFlag:invalidFlagId',...
'%u is an invalid flag id.',flagId(find(~isValid,1)))
end
end
end

methods
tf = isFlag(obj,flag)
end

methods (Static)
[bool,info] = validateId(id)
obj = id2validflag(id)
end

% Overloaded methods
methods
varargout = subsref(obj,s)
obj = cat(dim,varargin)
obj = horzcat(varargin)
obj = vertcat(varargin)
tf = eq(obj1,obj2)
end
end
68 changes: 68 additions & 0 deletions +DataKit/+Metadata/@dataFlag/disp.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
function disp(obj)
% disp Displays metadata of a dataFlag instance
% DISP displays metadata of a dataFlag instance. It overloads the
% builtin disp(x) function.
%
% Syntax
% data = DISP(obj)
%
% Description
% data = DISP(obj) displays metadata of a dataFlag instance.
%
% Example(s)
% data = DISP(obj)
%
%
% Input Arguments
% obj - dataFlag
% dataFlag
% An instance of the dataFlag class.
%
%
% Output Arguments
%
%
% Name-Value Pair Arguments
%
%
% See also SPARSEBITMASK
%
% Copyright 2021 David Clemens ([email protected])
%

import DataKit.ndigits

[i,j,v] = find(obj.Bitmask);
N = numel(i);
sz = size(obj.Bitmask);
Limit = 99;
LimitIsReached = N > Limit;
if LimitIsReached
n = Limit;
else
n = N;
end

tabLength = max([10,5 + ndigits(max(i)) + ndigits(max(j))]);

fprintf(' %ux%u <a href="matlab:help(''DataKit.Metadata.dataFlag'')">data flag</a>\n\n',sz(1),sz(2))

if N > 0
for ii = 1:n
flagIds = find(bitget(v(ii),1:52));
flagCellstr = cellstr(DataKit.Metadata.dataFlag.id2validflag(flagIds));
indexStr = sprintf('(%u, %u)',i(ii),j(ii));
fprintf('%s%s%s\n',indexStr,repmat(' ',1,tabLength - numel(indexStr)),strjoin(flagCellstr,', '))
end
if LimitIsReached
fprintf('%s:\n',repmat(' ',1,tabLength))
fprintf('%s:\n',repmat(' ',1,tabLength))
fprintf('%sOnly showing %u of %u elements.\n\n',repmat(' ',1,tabLength),n,N)
else
fprintf('\n')
fprintf('%sShowing %u of %u elements.\n\n',repmat(' ',1,tabLength),n,N)
end
else
fprintf('%sNo flag is set.\n\n',repmat(' ',1,tabLength))
end
end
13 changes: 13 additions & 0 deletions +DataKit/+Metadata/@dataFlag/eq.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function tf = eq(obj1,obj2)

if isa(obj1,'DataKit.Metadata.dataFlag') && isa(obj2,'DataKit.Metadata.dataFlag')
tf = isequal(obj1,obj2);
elseif ischar(obj2)
tf = obj1.isFlag(obj2);
elseif ischar(obj1)
tf = obj2.isFlag(obj1);
else
error('DataKit:Metadata:sparseBitmask:eq:invalidInputCombination',...
'Undefined input combination.')
end
end
4 changes: 4 additions & 0 deletions +DataKit/+Metadata/@dataFlag/horzcat.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function obj = horzcat(varargin)

obj = cat(2,varargin{:});
end
17 changes: 17 additions & 0 deletions +DataKit/+Metadata/@dataFlag/id2validflag.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function obj = id2validflag(id)

if ~isnumeric(id)
error('DataKit:Metadata:dataFlag:id2flag:invalidDataType',...
'The input argument ''id'' has to be numeric.')
end

flagListInfo = DataKit.Metadata.validators.validFlag.listAllValidFlagInfo();
[im,imIdx] = ismember(id,flagListInfo{:,'Id'});

if ~all(im)
error('DataKit:Metadata:dataFlag:id2flag:invalidFlagId',...
'The flag id %u is invalid.',id(find(~im,1)))
end

obj = flagListInfo{imIdx,'Flag'};
end
19 changes: 19 additions & 0 deletions +DataKit/+Metadata/@dataFlag/isFlag.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function tf = isFlag(obj,flag)

if ~ischar(flag) && ~isscalar(flag)
error('DataKit:Metadat:dataFlag:isFlag:onlyScalarContextAllowed',...
'''flag'' has to be scalar.')
end

if isnumeric(flag)
[isValid,info] = DataKit.Metadata.dataFlag.validateId(flag);
Flag = info{isValid,'Flag'};
else
Flag = DataKit.Metadata.validators.validFlag(flag);
end

[i,j,bm] = find(obj.Bitmask);

tf = false(size(obj));
tf(sub2ind(obj.Sz,i,j)) = logical(bitget(bm,Flag.Id));
end
44 changes: 44 additions & 0 deletions +DataKit/+Metadata/@dataFlag/subsref.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function varargout = subsref(obj,s)

switch s(1).type
case '.'
% if length(s) == 1
% % Implement obj.PropertyName
% ...
% elseif length(s) == 2 && strcmp(s(2).type,'()')
% % Implement obj.PropertyName(indices)
% ...
% else
% varargout = {builtin('subsref',obj,s)};
% end
varargout = {builtin('subsref',obj,s)};
case '()'
if length(s) == 1
% Implement obj(indices)
varargout = {DataKit.Metadata.dataFlag(obj.Bitmask(s.subs{:}))};
% elseif length(s) == 2 && strcmp(s(2).type,'.')
% % Implement obj(ind).PropertyName
% ...
% elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()')
% % Implement obj(indices).PropertyName(indices)
% ...
else
% Use built-in for any other expression
varargout = {builtin('subsref',obj,s)};
end
case '{}'
% if length(s) == 1
% % Implement obj{indices}
% ...
% elseif length(s) == 2 && strcmp(s(2).type,'.')
% % Implement obj{indices}.PropertyName
% ...
% else
% % Use built-in for any other expression
% varargout = {builtin('subsref',obj,s)};
% end
varargout = {builtin('subsref',obj,s)};
otherwise
error('Not a valid indexing expression')
end
end
11 changes: 11 additions & 0 deletions +DataKit/+Metadata/@dataFlag/validateId.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function [bool,info] = validateId(id)

if ~isnumeric(id)
error('DataKit:Metadata:dataFlag:validateId:invalidIdDataType',...
'''id'' has to be numeric.')
end

infoAll = DataKit.Metadata.validators.validFlag.listAllValidFlagInfo;
[bool,imIdx] = ismember(id,infoAll{:,'Id'});
info = infoAll(imIdx(bool),:);
end
4 changes: 4 additions & 0 deletions +DataKit/+Metadata/@dataFlag/vertcat.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function obj = vertcat(varargin)

obj = cat(1,varargin{:});
end
1 change: 1 addition & 0 deletions +DataKit/+Metadata/@info/info.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
obj = removeVariable(obj,ind)
tbl = info2table(obj)
obj = selectVariable(obj,variableIdx)
tf = isequal(objA,objB)
end
methods (Access = private)
obj = validateProperties(obj)
Expand Down
4 changes: 0 additions & 4 deletions +DataKit/+Metadata/@info/info2table.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
function tbl = info2table(obj)

if numel(obj) == 1
try
tbl = table(...
(1:obj.VariableCount)',...
obj.Variable',...
Expand All @@ -14,9 +13,6 @@
obj.VariableOffset',...
obj.VariableMeasuringDevice',...
'VariableNames',{'VariableIndex','Variable','Id','Type','Unit','Description','Origin','Factor','Offset','MeasuringDevice'});
catch

end
else
error('Only works in a scalar context')
end
Expand Down
Loading