changes from zurich; my mac

This commit is contained in:
Silas
2025-02-20 05:38:09 +01:00
parent cf94b67828
commit cb4caf8778
15 changed files with 434 additions and 0 deletions

179
Classes/Moveit_wrapper.m Normal file
View File

@@ -0,0 +1,179 @@
classdef Moveit_wrapper < handle
%
properties(Access=public)
moveit_function_name
para
state = struct()
comment
end
methods (Access=public)
function obj = Moveit_wrapper(moveit_function_name,options)
%
arguments
moveit_function_name
options.para
end
obj.moveit_function_name = moveit_function_name;
fn = fieldnames(options);
for n = 1:numel(fn)
try
obj.(fn{n}) = options.(fn{n});
end
end
% Ensure the function exists
if ~exist(obj.moveit_function_name, 'file')
error('Function "%s" does not exist.', obj.moveit_function_name);
end
% Step 1: Get default parameters by calling moveit module
if isempty(obj.para)
global loop;
loop = 0; % Request parameter structure
[obj.para, obj.comment] = feval(obj.moveit_function_name);
end
end
function signalclass_out = process(obj,signal_in)
isSignalClass = 0;
if isa(signal_in,"Signal")
signalclass_out = signal_in;
signal_in = signal_in.signal;
isSignalClass = 1;
end
input_len = length(signal_in);
signal_in = signal_in.';
% INIT MOVEIT
global loop;
loop = 0;
signal_out = obj.moveit_init(signal_in);
% RUN MOVEIT
global loop;
loop = 1;
signal_out = obj.moveit_init(signal_out);
% CHECK IF SIGNAL CHANGED
if input_len ~= length(signal_out)
warning(['Signal length changed in moveit function: ', obj.moveit_function_name]);
end
if isSignalClass
% append to logbook
lbdesc = ['Logbookentry'];
signalclass_out = signalclass_out.logbookentry(lbdesc);
signalclass_out.signal = signal_out;
end
end
function open_settings(obj)
% Opens a settings dialog for modifying Moveit parameters with appropriate input types.
% Inserts separators when the level value changes.
fieldNames = fieldnames(obj.para);
settingsCell = {};
previousLevel = -inf; % Track previous level for separators
% Create input arguments for settingsdlg
for i = 1:numel(fieldNames)
fieldName = fieldNames{i};
value = obj.para.(fieldName);
% Get description from comment structure if available
if isfield(obj.comment, fieldName)
description = obj.comment.(fieldName);
else
description = fieldName; % Default to field name if no description
end
% Get level for this parameter
if isfield(obj.comment.level, fieldName)
currentLevel = obj.comment.level.(fieldName);
else
currentLevel = 1; % Default level
end
% Insert separator if the level changes
if currentLevel ~= previousLevel
settingsCell{end+1} = 'separator';
settingsCell{end+1} = ['Level ', num2str(currentLevel)];
end
previousLevel = currentLevel;
% Determine input type from obj.comment.type
if
inputType = obj.comment.type.(fieldName);
else
inputType = 'number'; % Default type
end
% Add field description
settingsCell{end+1} = {description; fieldName};
% Define the input type
if strcmp(inputType, 'boolean')
% Checkbox input
settingsCell{end+1} = logical(value); % Enable checkbox
elseif contains(inputType, '|')
% Dropdown selection (options separated by '|')
dropdownOptions = strsplit(inputType, '|');
settingsCell{end+1} = dropdownOptions;
else
% Default: Numeric input
settingsCell{end+1} = value;
end
end
% Open settings dialog
[newValues, button] = settingsdlg(...
'title', ['Settings: ', obj.moveit_function_name], ...
'description', ['Adjust parameters for ', obj.moveit_function_name], ...
settingsCell{:} ...
);
% Update obj.para with new values only if "OK" was pressed
if strcmp(button, 'OK')
fieldNames = fieldnames(newValues);
for i = 1:numel(fieldNames)
if fieldNames{i}
end
obj.para.(fieldNames{i}) = newValues.(fieldNames{i});
end
end
end
end
methods (Access=private)
function data_out = moveit_init(obj,data_in)
arguments(Input)
obj
data_in double
end
% Step 2: Initialize the function
[data_out, obj.state] = feval(obj.moveit_function_name, data_in, obj.state, obj.para);
end
function data_out = moveit_simulation_computation(obj,data_in)
arguments(Input)
obj
data_in double
end
% Step 3: Process input signal
[data_out, obj.state] = feval(obj.moveit_function_name, data_in, obj.state, obj.para);
end
end
end

View File

@@ -0,0 +1,44 @@
classdef StorageParameter < handle
%PARAMETER Summary of this class goes here
% Detailed explanation goes here
properties
name
values
indices
length
getPhysForIndex = dictionary;
getIndexForPhys = dictionary;
end
methods
function obj = StorageParameter(name, values)
%PARAMETER Construct
obj.name = name;
obj.values = values;
obj.indices = [1:numel(obj.values)];
obj.length = length(obj.values);
obj = obj.buildIndexForPhysDict();
obj = obj.buildPhysForIndexDict();
end
function obj = buildPhysForIndexDict(obj)
%take Index
%return Phys
for idx = 1:numel(obj.values)
obj.getPhysForIndex(idx) = obj.values(idx);
end
end
function obj = buildIndexForPhysDict(obj)
%take Phys
%return Index
for idx = 1:numel(obj.values)
obj.getIndexForPhys(obj.values(idx)) = idx;
end
end
end
end

View File

@@ -0,0 +1,40 @@
function [data_out, state_out] = moveit_wrapper(func_name, data_in, para)
% Generic wrapper for legacy MATLAB functions using loop-based execution
%
% Usage:
% [data_out, state_out] = wrapper('quantize', data_in, para);
%
% Inputs:
% - func_name: Name of the function as a string (e.g., 'quantize')
% - data_in: Input signal or empty for initialization
% - para: Structure with parameters (optional)
%
% Outputs:
% - data_out: Processed output signal
% - state_out: Internal state of the function
global loop;
% Ensure the function exists
if ~exist(func_name, 'file')
error('Function "%s" does not exist.', func_name);
end
% Step 1: Get default parameters if not provided
if nargin < 3 || isempty(para)
loop = 0; % Request parameter structure
[para, comment] = feval(func_name);
end
% Initialize state
state = struct();
% Step 2: Initialize the function
loop = 0;
[~, state_] = feval(func_name, data_in, state, para);
% Step 3: Process input signal
loop = 1;
[data_out, state_out] = feval(func_name, data_in, state_, para);
end

View File

@@ -0,0 +1,91 @@
% Get the script folder
scriptFolder = fileparts(mfilename('fullpath'));
% Find the HDF5 file in the folder
files = dir(fullfile(scriptFolder, '*.h5'));
if isempty(files)
error('No HDF5 files found in the script folder.');
end
% Select the first matching file (modify as needed)
filename = files(6).name;
% filename = 'Pmod_8p0023dBm_P_PD_6p4776dBm_W03C34-0409E03_64GBd_2PAM__20250218T181323.h5';
% Extract parameters from the filename using an updated regex
tokens = regexp(filename, 'Pmod_([-0-9p]+)dBm_P_PD_([-0-9p]+)dBm_.*?_(\d+)GBd_(\d+)PAM__\d+T\d+', 'tokens');
if isempty(tokens)
error('Filename format not recognized.');
end
tokens = tokens{1};
% Convert values
P_laser = str2double(strrep(tokens{1}, 'p', '.'));
P_pd = str2double(strrep(tokens{2}, 'p', '.'));
fsym = str2double(tokens{3}) * 1e9; % Convert GBd to Hz
M = str2double(tokens{4});
% Display results
fprintf('Loaded file: %s\n', filename);
fprintf('P_laser: %.3f dBm\n', P_laser);
fprintf('P_pd: %.3f dBm\n', P_pd);
fprintf('fsym: %.3f Hz\n', fsym);
fprintf('M: %d\n', M);
%%% Load Data
folder = "/Users/silasoettinghaus/Documents/MATLAB/imdd_simulation/projects/Messung_Zürich";
filepath = fullfile(folder,filename);
ief_ = h5info(filepath);
fs_rx = h5readatt(filepath,'/','fs'); %sampling frequency at Rx
fs_tx = h5readatt(filepath, '/','fs_Tx'); %sampling frequency at Tx
fsym = h5readatt(filepath, '/','R'); %Baudrate
M = h5readatt(filepath, '/','M'); % PAM- 'M'
ROF = h5readatt(filepath, '/','ROF');
PulseShape =h5readatt(filepath, '/','PulseShape');
yOrg = h5readatt(filepath, ief_.Groups(4).Groups(1).Name, 'YOrg');
yInc = h5readatt(filepath, ief_.Groups(4).Groups(1).Name, 'YInc');
plotDisplayName = sprintf('P_{cw} = %.3f dBm, P_{PD} = %.3f dBm, f_{sym} = %.3f GBd, M = %d', ...
P_laser, P_pd, fsym / 1e9, M);
dataRx = double(h5read(filepath, '/Waveforms/Channel 2/Channel 2Data')); % rohdaten des CH4
bitsTx = h5read(filepath, '/Settings/dataTx'); %Binär
bitsTx = reshape(bitsTx,log2(M),[])';
%%% Build Tx Signal (Bits, Pam Map, Symbols)
Tx_bits = Informationsignal(bitsTx);
Tx_symbols = PAMmapper(M,0,"eth_style",1).map(Tx_bits);
Tx_symbols.fs = fsym;
% Tx_symbols.plot("fignum",1,"displayname",'Rx Signal');
% Tx_symbols.move_it_spectrum("fignum",2,"displayname",'tx spectrum');
% Tx_symbols.spectrum("fignum",3,"displayname",'Rx Signal','normalizeTo0dB',0);
%%% Build Rx Signal (Rx, normalize,remove mean)
dataRx = dataRx*yInc+yOrg;
Rx_Sig = Informationsignal(dataRx,"fs",fs_rx);
Rx_Sig = Rx_Sig.normalize("mode","rms");
% Rx_Sig.power();
% Rx_Sig.eye(fsym,M,"fignum",4,"displayname",'eye diagram');
% Rx_Sig.plot("fignum",5,"displayname",'Rx Signal');
% Rx_Sig.move_it_spectrum("fignum",6,"displayname",'tx spectrum');
Rx_Sig.spectrum("fignum",3,"displayname",'Rx Signal','normalizeTo0dB',0);
%%%%%% Sample to 2x fsym %%%%%%
Rx_Sig_resamp = Rx_Sig.resample("fs_out",2*fsym);
%%%%%% Sync Rx signal with reference (S is a cell array with all occurences) %%%%%%
[Rx_Sig_sync,S,isFlipped] = Rx_Sig_resamp.tsynch("reference",Tx_symbols,"fs_ref",fsym,"debug_plots",0);
eq_vnle_dfe = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",1,"ideal_dfe",0);
[result] = vnle(eq_vnle_dfe,M,Rx_Sig_sync,Tx_symbols,Tx_bits,"precode_mode",db_mode.no_db,"showAnalysis",1,'eth_style',1);

View File

@@ -0,0 +1,51 @@
%%% Run parameters
% TX
M = 4;
fsym = 32e9;
apply_pulsef = 1;
fdac = 256e9;
fadc = 256e9;
random_key = 1;
precomp = 0;
db_precode = 0;
db_encode = 0;
rcalpha = 0.05;
kover = 16;
vbias_rel = 0.5;
u_pi = 2.9;
vbias = -vbias_rel*u_pi;
laser_wavelength = 1293;
laser_linewidth = 0;
tx_bw_nyquist = 0.8;
% 1) PRBS Generation
O = 18; %order of prbs
N = 2^(O-1); %length of prbs
rcalpha = 1;
Pform = Pulseformer("fsym",fsym,"fdac",fdac,"pulse","rrc","pulselength",1024,"alpha",rcalpha);
[Digi_sig,Symbols,Tx_bits] = PAMsource(...
"fsym",fsym,"M",M,"order",18,"useprbs",0,...
"fs_out",fdac,...
"applyclipping",0,"clipfactor",1.5,...
"applypulseform",apply_pulsef,"pulseformer",Pform,...
"randkey",random_key,...
"db_precode",db_precode,"db_encode",db_encode,...
"mrds_code",0,"mrds_blocklength",512).process();
Digi_sig.spectrum("displayname",'Signal after shaping','fignum',1);
% Digi_sig.move_it_spectrum("displayname",'Signal after shaping','fignum',2);
% Digi_sig = Digi_sig.resample("fs_out",fsym);
MF = Pulseformer("fsym",fsym,"fdac",fdac,"pulse","rrc","pulselength",1024,"alpha",rcalpha,"matched",0);
Digi_sig = MF.process(Digi_sig);
Digi_sig.spectrum("displayname",'Signal after shaping','fignum',1);

29
test/test_mapping_eth.m Normal file
View File

@@ -0,0 +1,29 @@
% Setup PRBS parameters
O = 12;
M = 2;
N = 2^(O-1); % Length of PRBS
randkey = 1; % Random key for random stream
[~, seed] = prbs(O, 1); % Initialize first seed of PRBS
bitpattern = [];
s = RandStream('twister', 'Seed', randkey);
for i = 1:log2(M)
bitpattern(:, i) = randi(s, [0 1], N, 1);
end
Tx_bits = Informationsignal(bitpattern);
Digi_Mod = PAMmapper(M, 0,"eth_style",1);
% Map bits to symbols
Symbols = Digi_Mod.map(Tx_bits);
% Demap symbols back to bits
Rx_bits = Digi_Mod.demap(Symbols);
[~, error_num, ber, ~] = calc_ber(Tx_bits.signal, Rx_bits.signal, ...
"skip_front", 0, "skip_end", 0, "returnErrorLocation", 1);
fprintf('BER VNLE: %.1E \n',ber);