WDM code added (Pol Cont., Opt MUX/DEMUX, Opt Atten, DP_Fiber) -> the codebase is not optimized to always work with dp signals!
346 lines
13 KiB
Matlab
346 lines
13 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 e
|
|
disp(e.message)
|
|
disp('Provide save path')
|
|
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) = StorageParameter(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
|
|
|
|
function addValueToStorageByLinIdx(obj, valueToStore ,storageVarName, lin_idx)
|
|
|
|
obj.sto.(storageVarName){lin_idx} = valueToStore;
|
|
|
|
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,'double')
|
|
value(i) = tmp ;
|
|
elseif 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 ;
|
|
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
|
|
|
|
|
|
|
|
function [phys_indices,param_name] = getPhysIndicesByLinIndex(obj, lin_idx)
|
|
% Converts a linear index into the corresponding physical parameter values
|
|
% Inputs:
|
|
% - lin_idx: The linear index within the storage array
|
|
% Output:
|
|
% - phys_indices: A cell array containing the physical parameter values for each dimension
|
|
|
|
% Initialize output cell array
|
|
phys_indices = cell(1, numel(obj.fn));
|
|
|
|
% Convert linear index to subscript indices
|
|
[subscripts{1:numel(obj.dim)}] = ind2sub(obj.dim, lin_idx);
|
|
|
|
% Map subscripts to physical values for each parameter
|
|
for i = 1:numel(obj.fn)
|
|
param_name{i} = obj.fn(i);
|
|
phys_indices{i} = obj.parameter.(param_name{i}).getPhysForIndex(subscripts{i});
|
|
end
|
|
end
|
|
|
|
function [physStruct, stored_value] = getPhysAndValueByLinIndex(obj, storageVarName, lin_idx)
|
|
% Retrieves a structure with physical parameter values as fieldnames,
|
|
% their corresponding parameter names as values, and the stored value
|
|
% for a given linear index.
|
|
% Inputs:
|
|
% - storageVarName: Name of the storage variable in obj.sto
|
|
% - lin_idx: The linear index within the storage array
|
|
% Outputs:
|
|
% - physStruct: A structure with physical parameter values as fieldnames
|
|
% and parameter names as values
|
|
% - stored_value: The value stored at the given linear index in the
|
|
% specified storage variable
|
|
|
|
% Initialize an empty structure
|
|
physStruct = struct();
|
|
|
|
% Convert linear index to subscript indices
|
|
[subscripts{1:numel(obj.dim)}] = ind2sub(obj.dim, lin_idx);
|
|
|
|
% Map subscripts to physical values and parameter names for each dimension
|
|
for i = 1:numel(obj.fn)
|
|
param_name = obj.fn(i);
|
|
phys_value = obj.parameter.(param_name).getPhysForIndex(subscripts{i});
|
|
|
|
% Add to the structure with phys_value as the fieldname and param_name as the value
|
|
physStruct.(param_name) = phys_value;
|
|
end
|
|
|
|
% Retrieve the stored value at the given linear index
|
|
stored_value = obj.sto.(storageVarName){lin_idx};
|
|
end
|
|
|
|
function num_elements = getLastLinIndice(obj)
|
|
% Returns all possible linear indices for the data structure
|
|
% Output:
|
|
% - lin_indices: A column vector containing all linear indices for the storage array
|
|
|
|
% Calculate the total number of elements in the storage array
|
|
num_elements = prod(obj.dim);
|
|
end
|
|
|
|
|
|
|
|
end
|
|
end
|
|
|