From cd5dd1de6872272b4449b754bc85e7e2a3b74213 Mon Sep 17 00:00:00 2001 From: Silas Date: Mon, 4 Nov 2024 09:41:21 +0100 Subject: [PATCH] from mac --- Classes/Warehouse_class/classes/DataStorage.m | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 Classes/Warehouse_class/classes/DataStorage.m diff --git a/Classes/Warehouse_class/classes/DataStorage.m b/Classes/Warehouse_class/classes/DataStorage.m new file mode 100644 index 0000000..a05ed3b --- /dev/null +++ b/Classes/Warehouse_class/classes/DataStorage.m @@ -0,0 +1,273 @@ +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') + 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 +