274 lines
10 KiB
Matlab
274 lines
10 KiB
Matlab
classdef DataStorage < handle
|
|
%DATASTORAGE Summary of this class goes here
|
|
% Detailed explanation goes here
|
|
|
|
properties
|
|
inputParams = struct;
|
|
parameter = struct;
|
|
fn = [];
|
|
dim = [];
|
|
sto = {};
|
|
% getPhysForIndex = struct;
|
|
% getIndexForPhys = struct;
|
|
end
|
|
|
|
methods
|
|
|
|
function obj = DataStorage(inputParams)
|
|
%DATASTORAGE Construct an instance of this class
|
|
% Detailed explanation goes here
|
|
|
|
% scheiß Variablenname
|
|
obj.inputParams = inputParams;
|
|
|
|
% Field Names
|
|
obj.fn = string(fieldnames(inputParams));
|
|
|
|
% _______________
|
|
% Two dicts that map between physical and array index :-)
|
|
% Dictionary: 10 km -> 3
|
|
% obj.getIndexForPhys = obj.buildIndexDict();
|
|
|
|
% Dictionary: 3 -> 10Km
|
|
% obj.getPhysForIndex = obj.buildPhysDict();
|
|
|
|
% _______________
|
|
% This is the 2nd Idea -> ecery given Param will be a class
|
|
% instance of "Parameter", therin user can access the dicts and
|
|
% informations... Have not decided which way is best..
|
|
obj = obj.buildParameter();
|
|
|
|
% get dimension of dataStorage
|
|
% e.g. if we have L = [1,2,10,80] and D=[8, 17, 21], we would
|
|
% need an array with dimesion [4,3].
|
|
obj.dim = obj.getDimension();
|
|
|
|
% finally, create the main storage as cell array
|
|
obj.sto = struct;
|
|
|
|
end
|
|
|
|
function save(obj,path)
|
|
try
|
|
save(path,"obj");
|
|
catch
|
|
|
|
end
|
|
end
|
|
|
|
function showInfo(obj)
|
|
disp("Data Structure with fields:");
|
|
fprintf('%-12s', 'Name'); fprintf('%1s', '| '); fprintf('%0s ', 'Dimension'); fprintf('%4s', '| '); fprintf('%0s ', 'Physical Values'); fprintf('\n');
|
|
disp('----------------------------------------------------------------');
|
|
for i = 1:numel(obj.fn)
|
|
|
|
fprintf('%-12s', char(obj.fn(i))); fprintf('%1s', '| '); fprintf('%8.1i ', obj.dim(i)); fprintf('%5s', '| '); fprintf('%-7s ', string(obj.parameter.(obj.fn(i)).values) ); fprintf('\n');
|
|
|
|
end
|
|
disp('----------------------------------------------------------------');
|
|
|
|
stofn = string(fieldnames(obj.sto));
|
|
for s = 1:numel(stofn)
|
|
nonempty = numel(find(~cellfun(@isempty,obj.sto.(stofn(s)))));
|
|
overall = numel(obj.sto.(stofn(s)));
|
|
fprintf('%-8s', 'Storage '); fprintf('%-10s', char(stofn(s))); fprintf('%4s', 'filled with '); fprintf('%-5s', num2str(nonempty)); fprintf('%-1s', ' entries -> '); fprintf('%-5s', num2str(nonempty/overall*100)); fprintf('%-1s', '% filled'); fprintf('\n');
|
|
|
|
end
|
|
end
|
|
|
|
function dim = getDimension(obj)
|
|
dim = zeros(1,numel(obj.fn));
|
|
for p = 1:numel(obj.fn)
|
|
%loop all parameter names and add their length :-)
|
|
dim(p)=obj.parameter.(obj.fn(p)).length;
|
|
end
|
|
end
|
|
|
|
function obj = buildParameter(obj)
|
|
|
|
for p = 1:numel(obj.fn)
|
|
name = obj.fn(p);
|
|
values = obj.inputParams.(name);
|
|
obj.parameter.(name) = Parameter(name,values);
|
|
end
|
|
|
|
end
|
|
|
|
function addStorage(obj,varName)
|
|
% add a storage
|
|
|
|
storage = cell(obj.dim);
|
|
|
|
obj.sto.(string(varName)) = storage;
|
|
|
|
end
|
|
|
|
function addValueToStorage(obj, valueToStore ,storageVarName, varargin)
|
|
|
|
if nargin-3 == numel(obj.fn)
|
|
lin_idx = obj.getIndicesByPhys(varargin);
|
|
obj.sto.(storageVarName){lin_idx} = valueToStore;
|
|
else
|
|
error('Specify all the indices to access the right place in storage!')
|
|
end
|
|
|
|
end
|
|
|
|
% Access Value(s)
|
|
function value = getStoValue(obj,storageVarName, varargin)
|
|
|
|
if nargin-2 == numel(obj.fn)
|
|
%es wurden aausreichend argumente übergeben :-)
|
|
%es gibt jedoch erstmal keinen Check ob die Reihenfolge
|
|
%richtig ist
|
|
value = [];
|
|
lin_idx = obj.getIndicesByPhys(varargin);
|
|
errcnt = 0;
|
|
for i=1:numel(lin_idx)
|
|
|
|
tmp = obj.sto.(storageVarName){lin_idx(i)};
|
|
if ~isempty(tmp)
|
|
|
|
if isa(tmp,'Signal') || isa(tmp,'struct') || isa(tmp,'Exfo_laser') || isa(tmp,'DC_supply')
|
|
if i == 1
|
|
value = {};
|
|
end
|
|
value{i} = tmp ;
|
|
|
|
elseif isa(tmp,'cell')
|
|
if isa(tmp{1},'Signal')
|
|
if i == 1
|
|
value = {};
|
|
end
|
|
value{i} = tmp{1} ;
|
|
else
|
|
value{i} = tmp{1} ;
|
|
end
|
|
|
|
else
|
|
|
|
try
|
|
if i == 1
|
|
value = {};
|
|
end
|
|
value{i} = tmp ;
|
|
catch
|
|
% value(i,:) = tmp(1:size(value,2)) ;
|
|
|
|
if size(value,2) < size(tmp,2)
|
|
|
|
diff = size(tmp,2) - size(value,2);
|
|
value(:,end+1:end+diff) = NaN(size(value,1),diff);
|
|
value(i,:) = tmp ;
|
|
|
|
elseif size(value,2) > size(tmp,2)
|
|
|
|
diff = size(value,2) - size(tmp,2);
|
|
tmp(:,end+1:end+diff) = NaN(1,diff);
|
|
value(i,:) = tmp ;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
else
|
|
errcnt = errcnt+1;
|
|
|
|
if errcnt < 3
|
|
%get back the n-dimensional subiondices...
|
|
[sub{1:length(size(obj.sto.(storageVarName)))}] = ind2sub(size(obj.sto.(storageVarName)),lin_idx(i));
|
|
|
|
%get back the physical representaion
|
|
word = [];
|
|
for phys_idx = 1:numel(obj.fn)
|
|
parametername = obj.fn(phys_idx);
|
|
word = [word,char(parametername),': ', num2str(obj.parameter.(parametername).getPhysForIndex(sub{phys_idx})),' ;'];
|
|
end
|
|
% warning(['Requested Data is not in Warehouse ', word]);
|
|
elseif errcnt == 3
|
|
% warning(['... ', word]);
|
|
end
|
|
|
|
end
|
|
if errcnt > 2
|
|
% warning([num2str(errcnt),' requested datapoint(s) not in warehouse.']);
|
|
end
|
|
|
|
|
|
end
|
|
else
|
|
error('Wrong Request using ExampleWarehouse.getStoValue(*parameter set*). Give me all the Parameters! Please!')
|
|
end
|
|
|
|
end
|
|
|
|
% Mapping for several Indices (calls the mapping for single index)
|
|
function lin_idx = getIndicesByPhys(obj,varargin)
|
|
%map _all_ phys. to indices - several calls of single mapping
|
|
|
|
inputsz = cellfun(@size,varargin{1},'UniformOutput',false);
|
|
inputmax = cell2mat(cellfun(@max,inputsz,'UniformOutput',false));
|
|
|
|
% I wrote this method for a single query, then refined it for vectorial
|
|
% inputs (which work fine), but lastly recognized that I
|
|
% destroyed single query... however, this if / else will fix it!
|
|
if sum(inputmax)==length(inputmax)
|
|
vecQuery = 1; %set any value to one
|
|
else
|
|
vecQuery = find(inputmax~=1); %position of vectorial queries
|
|
end
|
|
|
|
q={};
|
|
for i = 1:numel(vecQuery)
|
|
q{i} = varargin{1,1}{vecQuery(i)}; %the two vectors
|
|
end
|
|
|
|
combination = combvec(q{:}); %combine all possible combinations
|
|
|
|
for c = 1:length(combination)
|
|
%loop over all possible combinations
|
|
|
|
indices = {};
|
|
str = [];
|
|
|
|
for r = 1:numel(vecQuery)
|
|
%replace varargin with current query (could have been renamed... however it works)
|
|
varargin{1}{vecQuery(r)} = combination(r,c);
|
|
end
|
|
|
|
for p = 1:numel(obj.fn)
|
|
|
|
curPhysQuery = varargin{1}{p}; %can be: a) single value // b) range
|
|
|
|
curParameterName = obj.fn(p);
|
|
|
|
indices{end+1} = obj.getIndexByPhys(curParameterName,curPhysQuery);
|
|
|
|
% str = [str, ',indices{', num2str(p), '}'];
|
|
|
|
end
|
|
|
|
%append to index list :-)
|
|
fn_=fieldnames(obj.sto);
|
|
n_ = fn_{1};
|
|
lin_idx(c,:) = sub2ind(size(obj.sto.(n_)),indices{:});
|
|
% lin_idx(c,:) = eval(['sub2ind(size(obj.sto.',n_,')',str,');']);
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
% Mapping for single Index
|
|
function idx = getIndexByPhys(obj,fieldname,phys)
|
|
%map single phys to index
|
|
idx = obj.parameter.(fieldname).getIndexForPhys(phys);
|
|
end
|
|
|
|
|
|
|
|
end
|
|
end
|
|
|