Files
imdd_silas/Classes/Warehouse_class/classes/DataStorage.m
2024-10-29 14:39:43 +01:00

247 lines
9.2 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)
% try
tmp = obj.sto.(storageVarName){lin_idx(i)};
if ~isempty(tmp)
if isa(tmp,'Signal')
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} ;
end
else
value(i,:) = tmp ;
end
else
errcnt = errcnt+1;
value(i,:) = NaN ;
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
% catch
% error('Error in Datastorage: Something happened while looking up 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