commit old stuff from lab
This commit is contained in:
@@ -172,9 +172,9 @@ classdef Signal
|
|||||||
|
|
||||||
hold on;
|
hold on;
|
||||||
if isempty(options.color)
|
if isempty(options.color)
|
||||||
plot(t, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1);
|
plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1);
|
||||||
else
|
else
|
||||||
plot(t, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1,'Color',options.color);
|
plot(t* 1e6, sig(1:length(t)), 'DisplayName', dn, 'LineWidth', 0.1, 'Marker', '.', 'LineStyle','none', 'MarkerSize', 0.1,'Color',options.color);
|
||||||
end
|
end
|
||||||
% 2 c)
|
% 2 c)
|
||||||
% - xlabel if not already here: time in readable format (1 ms and not 1e-3 s)
|
% - xlabel if not already here: time in readable format (1 ms and not 1e-3 s)
|
||||||
@@ -187,10 +187,7 @@ classdef Signal
|
|||||||
ylabel('Amplitude');
|
ylabel('Amplitude');
|
||||||
end
|
end
|
||||||
|
|
||||||
% Convert time axis to milliseconds for readability
|
|
||||||
xticks = get(gca, 'XTick');
|
|
||||||
set(gca, 'XTick', xticks, 'XTickLabel', xticks * 1e6);
|
|
||||||
|
|
||||||
% Add legend if not already present
|
% Add legend if not already present
|
||||||
if isempty(get(gca, 'Legend'))
|
if isempty(get(gca, 'Legend'))
|
||||||
legend;
|
legend;
|
||||||
@@ -656,7 +653,7 @@ classdef Signal
|
|||||||
end
|
end
|
||||||
|
|
||||||
%%
|
%%
|
||||||
function [obj,S,isFlipped,sequenceFound] = tsynch(obj,options)
|
function [obj,S,inverted,sequenceFound,sequenceStarts] = tsynch(obj,options)
|
||||||
% time sync and cut
|
% time sync and cut
|
||||||
arguments
|
arguments
|
||||||
obj Signal
|
obj Signal
|
||||||
@@ -668,9 +665,9 @@ classdef Signal
|
|||||||
|
|
||||||
|
|
||||||
S = {};
|
S = {};
|
||||||
isFlipped=0;
|
inverted = -1;
|
||||||
sequenceFound = 0;
|
sequenceFound = 0;
|
||||||
|
sequenceStarts = [];
|
||||||
|
|
||||||
|
|
||||||
%normalize the signal
|
%normalize the signal
|
||||||
@@ -696,8 +693,10 @@ classdef Signal
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if mean(w) > 10 || mean(p) > 10
|
if mean(w) > 10
|
||||||
|
warning('No sync possible, check code of findpeaks! Look at correlation')
|
||||||
return
|
return
|
||||||
|
|
||||||
else
|
else
|
||||||
sequenceFound = 1;
|
sequenceFound = 1;
|
||||||
end
|
end
|
||||||
@@ -711,19 +710,19 @@ classdef Signal
|
|||||||
|
|
||||||
|
|
||||||
shifts = lags(pkpos);
|
shifts = lags(pkpos);
|
||||||
|
sequenceStarts = shifts;
|
||||||
% shifts = shifts(shifts>=0);
|
% shifts = shifts(shifts>=0);
|
||||||
|
|
||||||
if numel(shifts) > 0
|
if numel(shifts) > 0
|
||||||
|
|
||||||
%Cut occurences of ref signal from signal (only positive shifts)
|
%Cut occurences of ref signal from signal (only positive shifts)
|
||||||
if all(sign(co(pkpos)))
|
if all(sign(co(pkpos))==-1)
|
||||||
isFlipped = 1;
|
inverted = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
for c = shifts
|
for c = shifts
|
||||||
sig = obj.delay(-c,'mode','samples');
|
sig = obj.delay(-c,'mode','samples');
|
||||||
sig.signal = sig.signal(1:length(b)).*-isFlipped;
|
sig.signal = sig.signal(1:length(b)) .* -inverted;
|
||||||
S{end+1,1} = sig;
|
S{end+1,1} = sig;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
146
Classes/05_Lab/OptLaserN7714A.m
Normal file
146
Classes/05_Lab/OptLaserN7714A.m
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
classdef OptLaserN7714A < handle
|
||||||
|
% Minimal controller for Keysight N7714A tunable laser over VISA-LAN
|
||||||
|
% Methods: getLaserInfo, setPower, setWavelength
|
||||||
|
%
|
||||||
|
% Examples:
|
||||||
|
% L = OptLaserN7714A('TCPIP::192.168.0.50::INSTR');
|
||||||
|
% L.setWavelength(1550); % nm
|
||||||
|
% L.setPower(-3.0, true); % dBm, also turns output ON
|
||||||
|
% info = L.getLaserInfo();
|
||||||
|
|
||||||
|
properties (Access=private)
|
||||||
|
v % visadev handle
|
||||||
|
resource char % VISA resource string, e.g. 'TCPIP::...::INSTR'
|
||||||
|
end
|
||||||
|
|
||||||
|
methods
|
||||||
|
function obj = OptLaserN7714A(resource)
|
||||||
|
arguments
|
||||||
|
resource (1,:) char
|
||||||
|
end
|
||||||
|
obj.resource = resource;
|
||||||
|
|
||||||
|
% Robust connect with small retry loop
|
||||||
|
maxRetries = 3; pauseTime = 1.0; lastErr = [];
|
||||||
|
for k = 1:maxRetries
|
||||||
|
try
|
||||||
|
obj.v = visadev(obj.resource);
|
||||||
|
% Identify instrument (SCPI *IDN?)
|
||||||
|
writeline(obj.v, '*IDN?'); % SCPI common, identification
|
||||||
|
idn = strtrim(readline(obj.v)); %#ok<NASGU>
|
||||||
|
break
|
||||||
|
catch ME
|
||||||
|
lastErr = ME;
|
||||||
|
pause(pauseTime);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if isempty(obj.v) || ~isvalid(obj.v)
|
||||||
|
error('OptLaserN7714A:ConnectFailed', ...
|
||||||
|
'Could not connect to %s. Last error: %s', obj.resource, lastErr.message);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Set power unit to dBm for SOURce tree to be explicit (optional)
|
||||||
|
% [:SOUR]:POWer:UNIT dBm (laser power unit)
|
||||||
|
% Ref: SOURce:POWer:UNIT. :contentReference[oaicite:0]{index=0}
|
||||||
|
try
|
||||||
|
writeline(obj.v, 'SOUR:POW:UNIT DBM');
|
||||||
|
catch
|
||||||
|
% non-fatal
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function delete(obj)
|
||||||
|
if ~isempty(obj.v) && isvalid(obj.v); delete(obj.v); end
|
||||||
|
end
|
||||||
|
|
||||||
|
function setPower(obj, power_dBm, outputOn, channel)
|
||||||
|
arguments
|
||||||
|
obj
|
||||||
|
power_dBm (1,1) double
|
||||||
|
outputOn (1,1) logical = true
|
||||||
|
channel (1,1) double {mustBeMember(channel,0:4)} = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
v = obj.v;
|
||||||
|
cmd = sprintf('SOUR%d:POW:LEV:IMM:AMPL %g DBM', channel, power_dBm);
|
||||||
|
writeline(v, cmd);
|
||||||
|
|
||||||
|
if outputOn
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:STAT 1', channel)); %SOUR1:POW:STAT 0
|
||||||
|
else
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:STAT 0', channel));
|
||||||
|
end
|
||||||
|
|
||||||
|
writeline(v, '*OPC?');
|
||||||
|
a=readline(v);
|
||||||
|
end
|
||||||
|
|
||||||
|
function setWavelength(obj, wavelength_nm, channel)
|
||||||
|
arguments
|
||||||
|
obj
|
||||||
|
wavelength_nm (1,1) double {mustBePositive}
|
||||||
|
channel (1,1) double {mustBeMember(channel,0:4)} = 1
|
||||||
|
end
|
||||||
|
v = obj.v;
|
||||||
|
cmd = sprintf('SOUR%d:WAV %gNM', channel, wavelength_nm);
|
||||||
|
writeline(v, cmd);
|
||||||
|
writeline(v, '*OPC?'); readline(v);
|
||||||
|
end
|
||||||
|
|
||||||
|
function setDither(obj, enable, port)
|
||||||
|
% Enable or disable laser frequency dither (stabilization).
|
||||||
|
% enable = false → no dither (FIX), true → stabilization (STAB).
|
||||||
|
% port = 1..4 (default 1).
|
||||||
|
if nargin < 3
|
||||||
|
port = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
v = obj.v;
|
||||||
|
if enable
|
||||||
|
writeline(v, sprintf('SOUR%d:CONTrol:FCDither ON', port)); %[:SOURce[n]][:CHANnel[m]]:CONTrol:FCDither
|
||||||
|
else
|
||||||
|
writeline(v, sprintf('SOUR%d:CONTrol:FCDither OFF', port));
|
||||||
|
end
|
||||||
|
|
||||||
|
% optional confirmation
|
||||||
|
writeline(v, sprintf('SOUR%d:CONTrol:FCDither?', port));
|
||||||
|
modeStr = strtrim(readline(v));
|
||||||
|
fprintf('Port %d dither mode set to %s\n', port, modeStr);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function info = getLaserInfo(obj, port)
|
||||||
|
% Returns struct with IDN, output state, wavelength (nm), power (dBm)
|
||||||
|
% port = 1..4 (for N7714A with 4 outputs). Default = 1.
|
||||||
|
if nargin < 2
|
||||||
|
port = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
v = obj.v;
|
||||||
|
|
||||||
|
% *IDN?
|
||||||
|
writeline(v, '*IDN?');
|
||||||
|
idn = strtrim(readline(v));
|
||||||
|
|
||||||
|
% Output state: :SOURn:POW:STAT?
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:STAT?', port));
|
||||||
|
out_state = str2double(readline(v)) ~= 0;
|
||||||
|
|
||||||
|
% Wavelength query (returns meters → convert to nm)
|
||||||
|
writeline(v, sprintf('SOUR%d:WAV?', port));
|
||||||
|
wav_m = str2double(readline(v));
|
||||||
|
wav_nm = wav_m * 1e9;
|
||||||
|
|
||||||
|
% Power (set level) query (dBm)
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:LEV:IMM:AMPL?', port));
|
||||||
|
p_dBm = str2double(readline(v));
|
||||||
|
|
||||||
|
info = struct('idn', idn, ...
|
||||||
|
'output_on', out_state, ...
|
||||||
|
'wavelength_nm', wav_nm, ...
|
||||||
|
'power_dBm', p_dBm);
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -17,6 +17,7 @@ if ~isempty(options.postFFE)
|
|||||||
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,tx_symbols);
|
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,tx_symbols);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
eq_signal.eye(eq_signal.fs,M,"fignum",340);
|
||||||
|
|
||||||
eq_signal = mlse_.process(eq_signal);
|
eq_signal = mlse_.process(eq_signal);
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ equalizerConfigDBsignaling = struct( ...
|
|||||||
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
||||||
'db_target', 1, ... % 0 oder 1
|
'db_target', 1, ... % 0 oder 1
|
||||||
'diff_precode', 1, ... % 0 oder 1
|
'diff_precode', 1, ... % 0 oder 1
|
||||||
'postFFE', ~isempty(options.postFFE), ... % Beispielwert
|
'postFFE', double(~isempty(options.postFFE)), ... % Beispielwert
|
||||||
'NpostFFE', npostFFE, ... % Beispielwert
|
'NpostFFE', npostFFE, ... % Beispielwert
|
||||||
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
||||||
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ end
|
|||||||
[gmi_vnle] = calc_air(eq_signal_sd,tx_symbols,"skip_front",10000,"skip_end",10000);
|
[gmi_vnle] = calc_air(eq_signal_sd,tx_symbols,"skip_front",10000,"skip_end",10000);
|
||||||
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
||||||
[evm_vnle_total,evm_vnle_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
[evm_vnle_total,evm_vnle_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
||||||
|
[std_vnle_total,std_vnle_lvl] = calc_std(eq_signal_sd,tx_symbols);
|
||||||
|
[std_rxraw_total,std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols);
|
||||||
|
|
||||||
% METRICS OF MLSE (HD-VITERBI)
|
% METRICS OF MLSE (HD-VITERBI)
|
||||||
pf_.ncoeff = 1;
|
pf_.ncoeff = 1;
|
||||||
@@ -127,6 +129,10 @@ resultsVNLE = struct( ...
|
|||||||
'numBitErr_precoded', errors_vnle_diff_precoded, ... % Beispiel: 120 Bitfehler
|
'numBitErr_precoded', errors_vnle_diff_precoded, ... % Beispiel: 120 Bitfehler
|
||||||
'SNR', snr_vnle, ... % Beispielhafte SNR
|
'SNR', snr_vnle, ... % Beispielhafte SNR
|
||||||
'SNR_level', jsonencode(snr_vnle_lvl), ... % SNR-Level als JSON-codiertes Array
|
'SNR_level', jsonencode(snr_vnle_lvl), ... % SNR-Level als JSON-codiertes Array
|
||||||
|
'STD', std_vnle_total, ...
|
||||||
|
'STD_level', jsonencode(std_vnle_lvl),...
|
||||||
|
'STDrx' , std_rxraw_total, ...
|
||||||
|
'STDrx_level', jsonencode(std_rxraw_lvl),...
|
||||||
'GMI', gmi_vnle, ... % Beispielhafter GMI-Wert
|
'GMI', gmi_vnle, ... % Beispielhafter GMI-Wert
|
||||||
'AIR', air_vnle, ... % Beispielhafter AIR-Wert
|
'AIR', air_vnle, ... % Beispielhafter AIR-Wert
|
||||||
'EVM', evm_vnle_total, ... % Beispielhafte EVM
|
'EVM', evm_vnle_total, ... % Beispielhafte EVM
|
||||||
@@ -147,7 +153,7 @@ equalizerConfigVNLE = struct( ...
|
|||||||
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
||||||
'db_target', 0, ... % 0 oder 1
|
'db_target', 0, ... % 0 oder 1
|
||||||
'diff_precode', int32(options.precode_mode), ... % 0 oder 1
|
'diff_precode', int32(options.precode_mode), ... % 0 oder 1
|
||||||
'postFFE', ~isempty(options.postFFE), ... % Beispielwert
|
'postFFE', double(~isempty(options.postFFE)), ... % Beispielwert
|
||||||
'NpostFFE', npostFFE, ... % Beispielwert
|
'NpostFFE', npostFFE, ... % Beispielwert
|
||||||
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
||||||
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
||||||
@@ -202,7 +208,7 @@ equalizerConfigMLSE = struct( ...
|
|||||||
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
||||||
'db_target', 0, ... % 0 oder 1
|
'db_target', 0, ... % 0 oder 1
|
||||||
'diff_precode', int32(options.precode_mode), ... % 0 oder 1
|
'diff_precode', int32(options.precode_mode), ... % 0 oder 1
|
||||||
'postFFE', ~isempty(options.postFFE), ... % Beispielwert
|
'postFFE', double(~isempty(options.postFFE)), ... % Beispielwert
|
||||||
'NpostFFE', npostFFE, ... % Beispielwert
|
'NpostFFE', npostFFE, ... % Beispielwert
|
||||||
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
||||||
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
||||||
@@ -234,9 +240,12 @@ eq_package.resultsMLSE = resultsMLSE;
|
|||||||
eq_package.equalizerConfigVNLE = equalizerConfigVNLE;
|
eq_package.equalizerConfigVNLE = equalizerConfigVNLE;
|
||||||
eq_package.equalizerConfigMLSE = equalizerConfigMLSE;
|
eq_package.equalizerConfigMLSE = equalizerConfigMLSE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% eq_package.vnle_out = eq_signal_sd;
|
% eq_package.vnle_out = eq_signal_sd;
|
||||||
if options.showAnalysis
|
if options.showAnalysis
|
||||||
|
|
||||||
|
|
||||||
% fprintf(['VNLE EVM lvl: ',repmat('%.3f ',1,numel(evm_lvl)),' \n'],evm_lvl);
|
% fprintf(['VNLE EVM lvl: ',repmat('%.3f ',1,numel(evm_lvl)),' \n'],evm_lvl);
|
||||||
|
|
||||||
% fprintf('VNLE BER: %.2e \n',ber_vnle);
|
% fprintf('VNLE BER: %.2e \n',ber_vnle);
|
||||||
@@ -264,6 +273,10 @@ if options.showAnalysis
|
|||||||
figure(341);clf;
|
figure(341);clf;
|
||||||
showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",341);
|
showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",341);
|
||||||
|
|
||||||
|
showLevelScatter(eq_signal_sd,tx_symbols,"fignum",400);
|
||||||
|
|
||||||
|
showLevelScatter(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols,"fignum",401);
|
||||||
|
|
||||||
% autoArrangeFigures(3,3,2)
|
% autoArrangeFigures(3,3,2)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
129
Functions/EQ_visuals/showLevelScatter.m
Normal file
129
Functions/EQ_visuals/showLevelScatter.m
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
function showLevelScatter(eq_signal,ref_symbols,options)
|
||||||
|
arguments
|
||||||
|
eq_signal
|
||||||
|
ref_symbols
|
||||||
|
options.fignum (1,1) double = NaN % Default to NaN if not provided
|
||||||
|
options.displayname (1,:) char = '' % Default to an empty string if not provided
|
||||||
|
options.f_sym = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
if isa(eq_signal,'Signal')
|
||||||
|
options.f_sym = eq_signal.fs;
|
||||||
|
eq_signal = eq_signal.signal;
|
||||||
|
end
|
||||||
|
if isa(ref_symbols,'Signal')
|
||||||
|
ref_symbols = ref_symbols.signal;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Determine the figure number to use or create a new figure
|
||||||
|
if isnan(options.fignum)
|
||||||
|
fig = figure; % Create a new figure and get its handle
|
||||||
|
else
|
||||||
|
fig = figure(options.fignum); % Use the specified figure number
|
||||||
|
clf;
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(~isempty(options.f_sym),'No fsym given');
|
||||||
|
|
||||||
|
rx_symbols = eq_signal ./ rms(eq_signal);
|
||||||
|
correct_symbols = ref_symbols;
|
||||||
|
f_sym = options.f_sym;
|
||||||
|
|
||||||
|
col = cbrewer2('Paired',numel(unique(correct_symbols))*2);
|
||||||
|
ccnt = -1;
|
||||||
|
|
||||||
|
levels = unique(correct_symbols);
|
||||||
|
|
||||||
|
start = 1;
|
||||||
|
ende = length(correct_symbols);
|
||||||
|
|
||||||
|
% start = 30000;
|
||||||
|
% ende = 40000;
|
||||||
|
|
||||||
|
for l = 1:numel(levels)
|
||||||
|
ccnt = ccnt+2;
|
||||||
|
|
||||||
|
level_amplitude = levels(l);
|
||||||
|
|
||||||
|
symbols_for_lvl = NaN(1,length(correct_symbols));
|
||||||
|
symbols_for_lvl(correct_symbols==level_amplitude) = rx_symbols(correct_symbols==level_amplitude);
|
||||||
|
std_lvl(l) = std(symbols_for_lvl,'omitnan');
|
||||||
|
xax_in_sec = ((1:length(correct_symbols)) / f_sym) * 1e6;
|
||||||
|
% xax_in_sec = 1:length(correct_symbols);
|
||||||
|
|
||||||
|
scatter(xax_in_sec(start:ende),symbols_for_lvl(start:ende),10,'.','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'MarkerEdgeColor',col(ccnt,:));
|
||||||
|
hold on;
|
||||||
|
end
|
||||||
|
|
||||||
|
std_lvl = round(std_lvl,2);
|
||||||
|
|
||||||
|
ccnt = 0;
|
||||||
|
|
||||||
|
% Add the windowed/ smoothed curves
|
||||||
|
for l = 1:numel(levels)
|
||||||
|
ccnt = ccnt+2;
|
||||||
|
level_amplitude = levels(l);
|
||||||
|
|
||||||
|
symbols_for_lvl = NaN(1,length(correct_symbols));
|
||||||
|
|
||||||
|
movmean = 1/250 .* movsum(rx_symbols(correct_symbols==level_amplitude),[250/2,250/2]);
|
||||||
|
|
||||||
|
symbols_for_lvl(correct_symbols==level_amplitude) = movmean;
|
||||||
|
|
||||||
|
nanx = isnan(symbols_for_lvl);
|
||||||
|
t = 1:numel(symbols_for_lvl);
|
||||||
|
symbols_for_lvl(nanx) = interp1(t(~nanx), symbols_for_lvl(~nanx), t(nanx));
|
||||||
|
|
||||||
|
xax_in_sec = ((1:length(correct_symbols)) / f_sym) * 1e6;
|
||||||
|
% xax_in_sec = 1:length(correct_symbols);
|
||||||
|
|
||||||
|
plot(xax_in_sec(start:ende),symbols_for_lvl(start:ende),'Color',col(ccnt,:));
|
||||||
|
hold on
|
||||||
|
end
|
||||||
|
|
||||||
|
%yline(max(rx_symbols(correct_symbols==levels(2))))
|
||||||
|
yline(levels);
|
||||||
|
|
||||||
|
if 0
|
||||||
|
annotation(fig,'textbox',...
|
||||||
|
[0.660523809523809 0.844444444444448 0.133523809523809 0.0603174603174607],...
|
||||||
|
'String',['\sigma = ',num2str(std_lvl(4))],...
|
||||||
|
'LineWidth',1.8,...
|
||||||
|
'LineStyle','none',...
|
||||||
|
'FontSize',12,...
|
||||||
|
'FitBoxToText','off');
|
||||||
|
|
||||||
|
% Create textbox
|
||||||
|
annotation(fig,'textbox',...
|
||||||
|
[0.667666666666665 0.642857142857147 0.133523809523809 0.0603174603174607],...
|
||||||
|
'String',['\sigma = ',num2str(std_lvl(3))],...
|
||||||
|
'LineWidth',1.8,...
|
||||||
|
'LineStyle','none',...
|
||||||
|
'FontSize',12,...
|
||||||
|
'FitBoxToText','off');
|
||||||
|
|
||||||
|
% Create textbox
|
||||||
|
annotation(fig,'textbox',...
|
||||||
|
[0.671238095238093 0.442857142857148 0.133523809523809 0.0603174603174608],...
|
||||||
|
'String',['\sigma = ',num2str(std_lvl(2))],...
|
||||||
|
'LineWidth',1.8,...
|
||||||
|
'LineStyle','none',...
|
||||||
|
'FontSize',12,...
|
||||||
|
'FitBoxToText','off');
|
||||||
|
|
||||||
|
% Create textbox
|
||||||
|
annotation(fig,'textbox',...
|
||||||
|
[0.670047619047616 0.265079365079371 0.133523809523809 0.0603174603174608],...
|
||||||
|
'String',['\sigma = ',num2str(std_lvl(1))],...
|
||||||
|
'LineWidth',1.8,...
|
||||||
|
'LineStyle','none',...
|
||||||
|
'FontSize',12,...
|
||||||
|
'FitBoxToText','off');
|
||||||
|
end
|
||||||
|
|
||||||
|
% xlim([0, 2.6])
|
||||||
|
% ylim([-2 2])
|
||||||
|
xlabel('Time in $\mu$s');
|
||||||
|
ylabel('Normalized Amplitude');
|
||||||
|
|
||||||
|
end
|
||||||
68
Functions/Metrics/calc_std.m
Normal file
68
Functions/Metrics/calc_std.m
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
function [std_total,std_lvl] = calc_std(test_signal,reference_signal,options)
|
||||||
|
|
||||||
|
arguments(Input)
|
||||||
|
test_signal;
|
||||||
|
reference_signal;
|
||||||
|
options.skip_front = 0;
|
||||||
|
options.skip_end = 0;
|
||||||
|
options.returnErrorLocation = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
options.skip_end = abs(options.skip_end);
|
||||||
|
options.skip_front = abs(options.skip_front);
|
||||||
|
|
||||||
|
assert((options.skip_end+options.skip_front)<length(test_signal),"You can not skip more bits than overall length of data! Set skip_front or skip_end to lower value or check data_in");
|
||||||
|
|
||||||
|
if isa(reference_signal,'Signal')
|
||||||
|
reference_signal = reference_signal.signal;
|
||||||
|
end
|
||||||
|
|
||||||
|
if isa(test_signal,'Signal')
|
||||||
|
test_signal = test_signal.signal;
|
||||||
|
end
|
||||||
|
|
||||||
|
% TRIM
|
||||||
|
[test_signal,reference_signal]=trimseq(test_signal,reference_signal,options.skip_front,options.skip_end);
|
||||||
|
|
||||||
|
% CALC EVM
|
||||||
|
[std_total,std_lvl] = calc_std_(test_signal,reference_signal);
|
||||||
|
|
||||||
|
|
||||||
|
function [std_total,std_lvl] = calc_std_(test_signal,reference_signal)
|
||||||
|
|
||||||
|
assert(length(test_signal) == length(reference_signal),"Sequence length does not match");
|
||||||
|
|
||||||
|
error_vector = (test_signal-reference_signal);
|
||||||
|
|
||||||
|
%%% Overall EVM
|
||||||
|
std_total = std(test_signal);
|
||||||
|
|
||||||
|
test_signal = test_signal ./ rms(test_signal);
|
||||||
|
|
||||||
|
try
|
||||||
|
%%% Per Level EVM
|
||||||
|
k = unique(reference_signal);
|
||||||
|
for lvl = 1:length(k)
|
||||||
|
% lvl_errors = error_vector(reference_signal==k(lvl));
|
||||||
|
std_lvl(lvl) = std(test_signal(reference_signal==k(lvl)));
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
std_lvl = NaN;
|
||||||
|
warning('No EVM per level calculated')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [data_,reference_] = trimseq(data,reference,skipstart,skip_end)
|
||||||
|
|
||||||
|
data_ = data(skipstart+1:end-skip_end,:);
|
||||||
|
|
||||||
|
delta_bits = length(reference) - length(data);
|
||||||
|
|
||||||
|
skip_end = delta_bits + skip_end;
|
||||||
|
|
||||||
|
reference_ = reference(skipstart+1:end-skip_end,:);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
19
Functions/connect_database_test.m
Normal file
19
Functions/connect_database_test.m
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
datasource = "jdbc:mysql://134.245.243.254:3306/labor";
|
||||||
|
|
||||||
|
conn = database( ...
|
||||||
|
"labor", ... % Database name
|
||||||
|
"silas", ... % Username
|
||||||
|
"silas", ... % Password (or getSecret)
|
||||||
|
"Vendor", "MySQL", ...
|
||||||
|
"Server", "134.245.243.254", ...
|
||||||
|
"PortNumber", 3306, ...
|
||||||
|
"JDBCDriverLocation", "C:\Users\Silas\Documents\mysql-connector-j-9.3.0\mysql-connector-j-9.3.0.jar");
|
||||||
|
|
||||||
|
% Query all table names
|
||||||
|
sqlquery = "SHOW TABLES;";
|
||||||
|
results = fetch(conn, sqlquery);
|
||||||
|
|
||||||
|
% Display the table names
|
||||||
|
disp("Tables in the database:");
|
||||||
|
disp(results);
|
||||||
@@ -5,7 +5,7 @@ databasePath = 'Z:\2025\ECOC Silas\';
|
|||||||
|
|
||||||
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
database_name = 'ecoc2025_loops.db';
|
database_name = 'ecoc2025_loops.db';
|
||||||
db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
db = DBHandler("pathToDB", [databasePath, database_name],"type","mysql");
|
||||||
|
|
||||||
num_occ = 30;
|
num_occ = 30;
|
||||||
run_par = true;
|
run_par = true;
|
||||||
|
|||||||
@@ -230,7 +230,6 @@ for occ = 1:record_realizations
|
|||||||
|
|
||||||
fprintf("BER DB: %.2e \n",dbenc_package{occ}.resultsDBsignaling.BER);
|
fprintf("BER DB: %.2e \n",dbenc_package{occ}.resultsDBsignaling.BER);
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
||||||
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
database_name = 'ecoc2025_loops.db';
|
database_name = 'ecoc2025_loops.db';
|
||||||
% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
db = DBHandler("pathToDB", [databasePath, database_name],"type","mysql");
|
||||||
db = DBHandler("type","mysql");
|
% db = DBHandler("type","mysql");
|
||||||
num_occ = 1;
|
num_occ = 5;
|
||||||
run_par = false;
|
run_par = false;
|
||||||
run_id = 2589;
|
run_id = 1958;
|
||||||
[out, ~] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ);
|
[out, future] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ);
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ end
|
|||||||
precomp_path = "C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\";
|
precomp_path = "C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\";
|
||||||
precomp_fn = "precomp_1km_1mm_cable_70ghz_pd_shf_t850_2p8_bias_shot2";
|
precomp_fn = "precomp_1km_1mm_cable_70ghz_pd_shf_t850_2p8_bias_shot2";
|
||||||
precomp_mode = 2; %0=do nothing ; 1= measure; 2=precomp active
|
precomp_mode = 2; %0=do nothing ; 1= measure; 2=precomp active
|
||||||
run_lab_automation = 1;
|
run_lab_automation = 0;
|
||||||
|
|
||||||
%% Configuration
|
%% Configuration
|
||||||
|
|
||||||
conf = confRequest;
|
conf = confRequest;
|
||||||
referenceFields = fieldnames(db.tables.Configurations);
|
referenceFields = fieldnames(db.tables.Configurations);
|
||||||
|
|
||||||
assert(isequal(fieldnames(conf), referenceFields), 'Fieldnames do not match the reference structure!');
|
% assert(isequal(fieldnames(conf), referenceFields), 'Fieldnames do not match the reference structure!');
|
||||||
|
|
||||||
%% Lab Automation
|
%% Lab Automation
|
||||||
|
|
||||||
@@ -41,24 +41,65 @@ if run_lab_automation
|
|||||||
end
|
end
|
||||||
voa.set('value',[0,conf.pd_in_desired,conf.signal_attenuation,conf.interference_attenuation]);
|
voa.set('value',[0,conf.pd_in_desired,conf.signal_attenuation,conf.interference_attenuation]);
|
||||||
|
|
||||||
if voa.power_state(3) > -24 || voa.power_state(1)+ voa.atten_state(4) > -38
|
if voa.power_state(3) > -24 || voa.power_state(1)+ voa.atten_state(4) > -37
|
||||||
holdAndShowValue
|
holdAndShowValue
|
||||||
end
|
end
|
||||||
|
|
||||||
% PDFA
|
% PDFA
|
||||||
if ~exist('pdfa','var')
|
if ~exist('pdfa','var')
|
||||||
pdfa = Thor_PDFA("safety_mode",0,"serialport_number",'COM15');
|
pdfa = Thor_PDFA("safety_mode",0,"serialport_number",'COM15');
|
||||||
end
|
end
|
||||||
|
|
||||||
% Construct AWG and Scope Modules %%%%%%
|
|
||||||
fdac = 224e9;
|
|
||||||
fadc = 160e9;
|
|
||||||
Scp = ScopeKeysight("model","DSAZ634A",'autoscale',0,"fadc","GSa_160","channel",[0,0,1,0],"recordLen",recordlen,"removeDC",1,"extRef",1);
|
|
||||||
Awg = AwgKeysight("model","M8199A_ILV","fdac",fdac,"scaletodac",[1,1],"skews",[0,0],"voltages",[0,conf.v_awg]);
|
|
||||||
A2S = Awg2Scope(Awg,Scp,[0,0,3,0],"waitUntilClick",0);
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% if conf.symbolrate == 72e9
|
||||||
|
% if conf.pam_level == 2
|
||||||
|
% conf.v_awg = 0.55;
|
||||||
|
% conf.pulsef_alpha = 0.6;
|
||||||
|
% elseif conf.pam_level == 4
|
||||||
|
% conf.v_awg = 0.55;
|
||||||
|
% conf.pulsef_alpha =0.6;
|
||||||
|
% elseif conf.pam_level == 6
|
||||||
|
% conf.v_awg = 0.55;
|
||||||
|
% conf.pulsef_alpha = 0.6;
|
||||||
|
% elseif conf.pam_level == 8
|
||||||
|
% conf.v_awg = 0.55;
|
||||||
|
% conf.pulsef_alpha = 0.6;
|
||||||
|
% end
|
||||||
|
% elseif conf.symbolrate == 96e9
|
||||||
|
% if conf.pam_level == 2
|
||||||
|
% conf.v_awg = 0.8;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 4
|
||||||
|
% conf.v_awg = 0.8;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 6
|
||||||
|
% conf.v_awg = 0.8;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 8
|
||||||
|
% conf.v_awg = 0.8;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% end
|
||||||
|
% elseif conf.symbolrate == 112e9
|
||||||
|
% if conf.pam_level == 2
|
||||||
|
% conf.v_awg = 0.85;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 4
|
||||||
|
% conf.v_awg = 0.85;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 6
|
||||||
|
% conf.v_awg = 0.85;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% elseif conf.pam_level == 8
|
||||||
|
% conf.v_awg = 0.85;
|
||||||
|
% conf.pulsef_alpha = 0.2;
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
|
||||||
|
awg_upload_required = 1;
|
||||||
|
if any(confPrev.pam_level == conf.pam_level) && any(confPrev.symbolrate == conf.symbolrate)
|
||||||
|
awg_upload_required = 0;
|
||||||
|
end
|
||||||
|
|
||||||
%% Signal generation and transmission
|
%% Signal generation and transmission
|
||||||
if awg_upload_required || isempty(loop_id)
|
if awg_upload_required || isempty(loop_id)
|
||||||
@@ -69,6 +110,13 @@ if awg_upload_required || isempty(loop_id)
|
|||||||
sequence_order = min(18,sequence_order);
|
sequence_order = min(18,sequence_order);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Construct AWG and Scope Modules %%%%%%
|
||||||
|
fdac = 224e9;
|
||||||
|
fadc = 160e9;
|
||||||
|
Scp = ScopeKeysight("model","DSAZ634A",'autoscale',0,"fadc","GSa_160","channel",[0,0,1,0],"recordLen",recordlen,"removeDC",1,"extRef",1);
|
||||||
|
Awg = AwgKeysight("model","M8199A_ILV","fdac",fdac,"scaletodac",[1,1],"skews",[0,0],"voltages",[0,conf.v_awg]);
|
||||||
|
A2S = Awg2Scope(Awg,Scp,[0,0,3,0],"waitUntilClick",0);
|
||||||
|
|
||||||
Pamsource = PAMsource(...
|
Pamsource = PAMsource(...
|
||||||
"fsym",conf.symbolrate,"M",conf.pam_level,"order",sequence_order,"useprbs",1,...
|
"fsym",conf.symbolrate,"M",conf.pam_level,"order",sequence_order,"useprbs",1,...
|
||||||
"fs_out",fdac,...
|
"fs_out",fdac,...
|
||||||
@@ -79,11 +127,11 @@ if awg_upload_required || isempty(loop_id)
|
|||||||
"randkey",1,...
|
"randkey",1,...
|
||||||
"duobinary_mode", conf.db_mode);
|
"duobinary_mode", conf.db_mode);
|
||||||
|
|
||||||
conf.pam_source = Pamsource;
|
|
||||||
confPrev = conf;
|
|
||||||
|
|
||||||
[Digi_sig,Symbols,Bits] = Pamsource.process();
|
[Digi_sig,Symbols,Bits] = Pamsource.process();
|
||||||
|
|
||||||
|
figure(10);clf;
|
||||||
|
Digi_sig.spectrum("displayname",'Tx Pulse Shaped','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
|
|
||||||
%%%%% Precompensation Routine %%%%%%
|
%%%%% Precompensation Routine %%%%%%
|
||||||
if precomp_mode == 1 % measure channel
|
if precomp_mode == 1 % measure channel
|
||||||
@@ -94,11 +142,13 @@ if awg_upload_required || isempty(loop_id)
|
|||||||
Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',conf.precomp_amp,'loadPath',precomp_path,'fileName',precomp_fn);
|
Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',conf.precomp_amp,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Digi_sig.spectrum("displayname",'Tx Spectrum','fignum',10,'normalizeTo0dB',0);
|
Digi_sig.spectrum("displayname",'Tx Pre-Emphasized','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
%%%%% Resample to DAC rate %%%%%%
|
%%%%% Resample to DAC rate %%%%%%
|
||||||
Digi_sig = Digi_sig.resample("fs_out",Awg.fdac);
|
Digi_sig = Digi_sig.resample("fs_out",Awg.fdac);
|
||||||
|
|
||||||
|
Digi_sig.spectrum("displayname",'Tx Resampled','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
% [~,~,Scpe_sig_raw,~] = A2S.process("signal2",Digi_sig);
|
% [~,~,Scpe_sig_raw,~] = A2S.process("signal2",Digi_sig);
|
||||||
|
|
||||||
Awg.upload("signal2",Digi_sig);
|
Awg.upload("signal2",Digi_sig);
|
||||||
@@ -113,6 +163,8 @@ if precomp_mode == 1
|
|||||||
return; % End routine if precomp mode is active
|
return; % End routine if precomp mode is active
|
||||||
end
|
end
|
||||||
|
|
||||||
|
confPrev = conf;
|
||||||
|
|
||||||
%% Save static TX data (only once)
|
%% Save static TX data (only once)
|
||||||
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
|
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
|
||||||
timeStr = char(currentTime);
|
timeStr = char(currentTime);
|
||||||
@@ -142,7 +194,7 @@ for recIdx = 1:n_recording
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Plot spectrum and time domain (optional)
|
% Plot spectrum and time domain (optional)
|
||||||
% Scpe_sig_raw.spectrum("displayname", 'Rx Spectrum', 'fignum', 10, 'normalizeTo0dB', 0);
|
Scpe_sig_raw.spectrum("displayname", 'Rx Spectrum', 'fignum', 10, 'normalizeTo0dB', 0);
|
||||||
Scpe_sig_raw.plot("clear", 1, "displayname", 'Rx Signal', 'fignum', 11);
|
Scpe_sig_raw.plot("clear", 1, "displayname", 'Rx Signal', 'fignum', 11);
|
||||||
|
|
||||||
%% Save Routine
|
%% Save Routine
|
||||||
@@ -153,7 +205,6 @@ for recIdx = 1:n_recording
|
|||||||
rx_raw_path = [filesep, current_folder, filesep, filename, '_rx_signal_raw'];
|
rx_raw_path = [filesep, current_folder, filesep, filename, '_rx_signal_raw'];
|
||||||
save([savePath, rx_raw_path], "Scpe_sig_raw");
|
save([savePath, rx_raw_path], "Scpe_sig_raw");
|
||||||
|
|
||||||
|
|
||||||
% Check if loop_id is already created
|
% Check if loop_id is already created
|
||||||
if isempty(loop_id)
|
if isempty(loop_id)
|
||||||
newLoop = db.tables.LoopControl;
|
newLoop = db.tables.LoopControl;
|
||||||
@@ -165,7 +216,6 @@ for recIdx = 1:n_recording
|
|||||||
fprintf('LoopControl entry created: loop_id = %d\n', loop_id);
|
fprintf('LoopControl entry created: loop_id = %d\n', loop_id);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%% Append to Runs Table
|
%% Append to Runs Table
|
||||||
newRun = db.tables.Runs;
|
newRun = db.tables.Runs;
|
||||||
newRun.run_id = NaN;
|
newRun.run_id = NaN;
|
||||||
@@ -183,6 +233,8 @@ for recIdx = 1:n_recording
|
|||||||
%% Append to Configurations Table
|
%% Append to Configurations Table
|
||||||
conf.configuration_id = NaN;
|
conf.configuration_id = NaN;
|
||||||
conf.run_id = run_id;
|
conf.run_id = run_id;
|
||||||
|
conf.bitrate = conf.symbolrate .* floor(log2(6)*10)/10;
|
||||||
|
conf.pam_source = Pamsource;
|
||||||
db.appendToTable('Configurations', conf);
|
db.appendToTable('Configurations', conf);
|
||||||
|
|
||||||
%% Append to Measurements Table
|
%% Append to Measurements Table
|
||||||
@@ -210,6 +262,11 @@ for recIdx = 1:n_recording
|
|||||||
[out, a] = submit_dsp(run_id, databasePath, database_name, savePath, ...
|
[out, a] = submit_dsp(run_id, databasePath, database_name, savePath, ...
|
||||||
"parallel", parallel_dsp, "max_occurences", max_occurences);
|
"parallel", parallel_dsp, "max_occurences", max_occurences);
|
||||||
end
|
end
|
||||||
|
if awg_upload_required
|
||||||
|
[out, a] = submit_dsp(run_id, databasePath, database_name, savePath, ...
|
||||||
|
"parallel", 0, "max_occurences", 1);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
basePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
basePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
database_name = 'ecoc2025.db';
|
database_name = 'ecoc2025.db';
|
||||||
database = DBHandler("pathToDB", [basePath, database_name]);
|
database = DBHandler("pathToDB", [basePath, database_name],"type",'mysql');
|
||||||
|
|
||||||
filterParams = database.tables;
|
filterParams = database.tables;
|
||||||
filterParams.Configurations = struct( ...
|
filterParams.Configurations = struct( ...
|
||||||
|
|||||||
BIN
projects/ECOC_2025/precomp_1km.mat
Normal file
BIN
projects/ECOC_2025/precomp_1km.mat
Normal file
Binary file not shown.
BIN
projects/ECOC_2025/precomp_1km_1mm_cable.mat
Normal file
BIN
projects/ECOC_2025/precomp_1km_1mm_cable.mat
Normal file
Binary file not shown.
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_100ghz_pd.mat
Normal file
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_100ghz_pd.mat
Normal file
Binary file not shown.
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_70ghz_pd.mat
Normal file
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_70ghz_pd.mat
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_70ghz_pd_shot2.mat
Normal file
BIN
projects/ECOC_2025/precomp_1km_1mm_cable_70ghz_pd_shot2.mat
Normal file
Binary file not shown.
BIN
projects/Lab_base_system/exfo_control_app.mlapp
Normal file
BIN
projects/Lab_base_system/exfo_control_app.mlapp
Normal file
Binary file not shown.
15
projects/Lab_base_system/exfo_laser_example.m
Normal file
15
projects/Lab_base_system/exfo_laser_example.m
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
%% Laser
|
||||||
|
start_wavelength = 1550;
|
||||||
|
laser = Exfo_laser("mainframe_channel",3,"safety_mode",0,"connection_id",'10','lab_interface','gpib');
|
||||||
|
laser.getLaserInfo();
|
||||||
|
|
||||||
|
laser.setWavelength(start_wavelength)
|
||||||
|
laser.setPower(0);
|
||||||
|
|
||||||
|
laser.enableLaser();
|
||||||
|
for l = 1550:1560
|
||||||
|
laser.setWavelength(l);
|
||||||
|
end
|
||||||
|
|
||||||
|
laser.disableLaser();
|
||||||
|
|
||||||
74
projects/Lab_base_system/olaf_control.m
Normal file
74
projects/Lab_base_system/olaf_control.m
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
clear all
|
||||||
|
|
||||||
|
visastring = "GPIB0::22::INSTR";
|
||||||
|
v_pwrmtr = visadev(visastring);
|
||||||
|
writeline(v_pwrmtr, "*IDN?");
|
||||||
|
answ = readline(v_pwrmtr);
|
||||||
|
disp(['Yay! We can talk to Instrument: ',char(answ)]);
|
||||||
|
|
||||||
|
% laser = Exfo_laser("mainframe_channel",3,"safety_mode",0,"connection_id",'15','lab_interface','gpib');
|
||||||
|
% laser.getLaserInfo();
|
||||||
|
|
||||||
|
L = OptLaserN7714A("GPIB0::20::INSTR");
|
||||||
|
|
||||||
|
% visastring = 'GPIB0::10::INSTR';
|
||||||
|
% v_lsr = visadev(visastring);
|
||||||
|
% writeline(v_lsr, "*IDN?");
|
||||||
|
% answ = readline(v_lsr);
|
||||||
|
% disp(['Yay! We can talk to Instrument: ',char(answ)]);
|
||||||
|
|
||||||
|
steps = 100;
|
||||||
|
wavelength_sweep = linspace(1554,1556,steps);
|
||||||
|
start_wavelength = wavelength_sweep(1);
|
||||||
|
|
||||||
|
% laser.setWavelength(start_wavelength);
|
||||||
|
L.setWavelength(start_wavelength,0);
|
||||||
|
% laser.setPower(0);
|
||||||
|
% laser.enableLaser();
|
||||||
|
L.setPower(0, true,0);
|
||||||
|
|
||||||
|
|
||||||
|
pwr_save = NaN(size(wavelength_sweep));
|
||||||
|
for l = 1:numel(wavelength_sweep)
|
||||||
|
|
||||||
|
% 1)
|
||||||
|
% laser.setWavelength(wavelength_sweep(l));
|
||||||
|
L.setWavelength(wavelength_sweep(l),0);
|
||||||
|
%writeline(v_lsr, ['L=' num2str(wavelength_sweep(l))]);
|
||||||
|
|
||||||
|
% 2) Set Wavelength of Power Meter
|
||||||
|
t = string(['SENS2:POW:WAVE ',num2str(wavelength_sweep(l)),'NM']);
|
||||||
|
writeline(v_pwrmtr, t);
|
||||||
|
% writeline(v, "SENS:POW:WAVE?");
|
||||||
|
% wavel = readline(v);
|
||||||
|
|
||||||
|
% 3) Read Power of
|
||||||
|
writeline(v_pwrmtr, "READ2:POW?");
|
||||||
|
pwr = readline(v_pwrmtr);
|
||||||
|
pwr_save(l) = str2num(pwr);
|
||||||
|
|
||||||
|
figure(2025);clf
|
||||||
|
plot(wavelength_sweep,pwr_save,'Marker','*');
|
||||||
|
xlabel('Wavelength [nm]');
|
||||||
|
ylabel('Insertion Loss [dB]');
|
||||||
|
ylim([min(pwr_save)-1, min(pwr_save)+1]);
|
||||||
|
xlim([wavelength_sweep(1) wavelength_sweep(end)])
|
||||||
|
grid minor
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
% laser.disableLaser();
|
||||||
|
L.setPower(0, false,0);
|
||||||
|
L.delete();
|
||||||
|
|
||||||
|
%writeline(v_lsr, 'DISABLE');
|
||||||
|
|
||||||
|
path= "Z:\2025\NFT WDM DFG Olaf\lambda_vs_power";
|
||||||
|
|
||||||
|
dt = datetime('now','Format','yyyyMMdd_HHmmss');
|
||||||
|
filename = fullfile(path, "loop_5_7_"+num2str(wavelength_sweep(1)) +"nm_to_"+ num2str(wavelength_sweep(end))+ "nm_" + string(dt) + ".mat");
|
||||||
|
|
||||||
|
save(filename, "pwr_save","wavelength_sweep");
|
||||||
|
|
||||||
|
disp("Saved to: " + filename);
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
clear all
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
start_wavelength = 1554.2; %nm
|
||||||
|
stop_wavelength = 1555.7; %nm
|
||||||
|
steps = 100;
|
||||||
|
power = 0; %dBm
|
||||||
|
name = "south_board_total_loss_ports_21_20";
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
wavelength_sweep = linspace(start_wavelength,stop_wavelength,steps);
|
||||||
|
wavelength_1 = wavelength_sweep(1);
|
||||||
|
|
||||||
|
visastring = "GPIB0::22::INSTR";
|
||||||
|
v_pwrmtr = visadev(visastring);
|
||||||
|
%writeline(v_pwrmtr, "*IDN?");
|
||||||
|
%answ = readline(v_pwrmtr);
|
||||||
|
%disp(['Yay! We can talk to Instrument: ',char(answ)]);
|
||||||
|
|
||||||
|
L = OptLaserN7714A("GPIB0::20::INSTR");
|
||||||
|
L.setWavelength(wavelength_1,0);
|
||||||
|
L.setPower(power, true,0);
|
||||||
|
|
||||||
|
pwr_save = NaN(size(wavelength_sweep));
|
||||||
|
for l = 1:numel(wavelength_sweep)
|
||||||
|
|
||||||
|
% 1)
|
||||||
|
L.setWavelength(wavelength_sweep(l),0);
|
||||||
|
|
||||||
|
% 2) Set Wavelength of Power Meter
|
||||||
|
t = string(['SENS1:POW:WAVE ',num2str(wavelength_sweep(l)),'NM']);
|
||||||
|
writeline(v_pwrmtr, t);
|
||||||
|
|
||||||
|
% 3) Read Power of
|
||||||
|
writeline(v_pwrmtr, "READ1:POW?");
|
||||||
|
pwr = readline(v_pwrmtr);
|
||||||
|
pwr_save(l) = str2num(pwr);
|
||||||
|
|
||||||
|
figure(2026);clf
|
||||||
|
plot(wavelength_sweep,pwr_save,'Marker','*');
|
||||||
|
xlabel('Wavelength [nm]');
|
||||||
|
ylabel('Insertion Loss [dB]');
|
||||||
|
ylim([min(pwr_save)-1, max(pwr_save)+1]);
|
||||||
|
xlim([wavelength_sweep(1) wavelength_sweep(eind)])
|
||||||
|
grid minor
|
||||||
|
end
|
||||||
|
|
||||||
|
L.setPower(0, false,0);
|
||||||
|
L.delete();
|
||||||
|
|
||||||
|
path= "Z:\2025\NFT WDM DFG Olaf\lambda_vs_power";
|
||||||
|
|
||||||
|
dt = datetime('now','Format','yyyyMMdd_HHmmss');
|
||||||
|
filename = fullfile(path, name+"_"+replace(num2str(wavelength_sweep(1)),".","_") +"nm_to_"+ replace(num2str(wavelength_sweep(end)),".","_")+ "nm_" + string(dt) + ".mat");
|
||||||
|
|
||||||
|
save(filename, "pwr_save","wavelength_sweep");
|
||||||
|
|
||||||
|
disp("Saved to: " + filename);
|
||||||
21
projects/Lab_base_system/olaf_laser_control.m
Normal file
21
projects/Lab_base_system/olaf_laser_control.m
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
clear all
|
||||||
|
|
||||||
|
% L = OptLaserN7714A("TCPIP0::134.245.243.209::inst0::INSTR");
|
||||||
|
% L.setWavelength(1551,1); % nm
|
||||||
|
% L.setPower(5.8, true,1); % dBm, also turns output ON
|
||||||
|
% L.setDither(0,1);
|
||||||
|
% % L.setPower(5.9, false,1);
|
||||||
|
% info = L.getLaserInfo();
|
||||||
|
%
|
||||||
|
% L.delete();
|
||||||
|
|
||||||
|
|
||||||
|
clear all
|
||||||
|
|
||||||
|
L = OptLaserN7714A("GPIB0::20::INSTR");
|
||||||
|
L.setWavelength(1550,0); % nm
|
||||||
|
L.setPower(0, true,0); % dBm, also turns output ON
|
||||||
|
L.setPower(0, false,0);
|
||||||
|
info = L.getLaserInfo();
|
||||||
|
|
||||||
|
L.delete();
|
||||||
29
projects/Lab_base_system/olaf_laser_control_minimal.m
Normal file
29
projects/Lab_base_system/olaf_laser_control_minimal.m
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
% --- Minimal N7714A example (MATLAB) ---
|
||||||
|
visa_addr = "TCPIP0::134.245.243.209::inst0::INSTR"; % <-- change to your laser's IP
|
||||||
|
port = 1; % 1..4 selects the N7714A output port
|
||||||
|
|
||||||
|
% v = visadev(visa_addr);
|
||||||
|
|
||||||
|
% Identify instrument
|
||||||
|
writeline(v,'*IDN?'); disp(strtrim(readline(v)));
|
||||||
|
|
||||||
|
% Make sure wavelength is settable (Auto mode)
|
||||||
|
writeline(v, sprintf('SOUR%d:WAV:AUTO 1', port)); % Auto Mode ON (wavelength set allowed).
|
||||||
|
|
||||||
|
% Set wavelength and power (units explicit)
|
||||||
|
writeline(v, sprintf('SOUR%d:WAV 1560NM', port)); % set 1550 nm. :contentReference[oaicite:3]{index=3}
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:UNIT DBM', port)); % power unit = dBm. :contentReference[oaicite:4]{index=4}
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:LEV:IMM:AMPL 6 DBM', port)); % set -3 dBm. :contentReference[oaicite:5]{index=5}
|
||||||
|
|
||||||
|
% Enable output (either OUTP or SOUR:POW:STAT works)
|
||||||
|
writeline(v, sprintf('OUTP%d:STAT ON', port)); % laser ON. :contentReference[oaicite:6]{index=6}
|
||||||
|
writeline(v, 'OUTP1 ON');
|
||||||
|
|
||||||
|
% ---- Read back to verify ----
|
||||||
|
writeline(v, sprintf('SOUR%d:WAV?', port)); wav_m = str2double(readline(v));
|
||||||
|
writeline(v, sprintf('SOUR%d:POW:LEV:IMM:AMPL?', port)); pow = str2double(readline(v));
|
||||||
|
writeline(v, sprintf('OUTP%d:ON?', port)); onoff = str2double(readline(v));
|
||||||
|
|
||||||
|
fprintf('Port %d -> %.2f nm, %.2f dBm, Output=%d\n', port, 1e9*wav_m, pow, onoff);
|
||||||
|
|
||||||
|
delete(v);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
L.setPower(power, false,0);
|
||||||
|
L.delete();
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
clear all
|
||||||
|
|
||||||
|
% 1554.7097
|
||||||
|
% 1554.9032
|
||||||
|
% 1555.0968
|
||||||
|
% 1555.2904
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
wavelength = 1555.0968; %nm
|
||||||
|
power = 6; %dBm
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
L = OptLaserN7714A("GPIB0::20::INSTR");
|
||||||
|
|
||||||
|
L.setWavelength(wavelength,0);
|
||||||
|
L.setPower(power, true,0);
|
||||||
@@ -13,42 +13,45 @@ end
|
|||||||
|
|
||||||
database_name = 'ecoc2025_loops.db';
|
database_name = 'ecoc2025_loops.db';
|
||||||
|
|
||||||
if ~exist('db','var')
|
db = DBHandler("pathToDB", [databasePath, database_name]);
|
||||||
db = DBHandler("pathToDB", [databasePath, database_name]);
|
|
||||||
end
|
|
||||||
conf = db.tables.Configurations;
|
conf = db.tables.Configurations;
|
||||||
|
% conf = db.tables.Configurations;
|
||||||
if ~exist('confPrev','var')
|
if ~exist('confPrev','var')
|
||||||
confPrev = db.tables.Configurations;
|
confPrev = conf;
|
||||||
end
|
end
|
||||||
|
|
||||||
awg_upload_required = 1; %still uploads every first round
|
awg_upload_required = 1; %still uploads every first round
|
||||||
subimt_DSP = 1;
|
subimt_DSP = 1;
|
||||||
recordlen = 5000000;
|
recordlen = 1000000;
|
||||||
sequence_order = 19;
|
sequence_order = 17;
|
||||||
n_recording = 2; % Or any number you want
|
n_recording = 1; % Or any number you want
|
||||||
|
|
||||||
|
conf=rmfield(conf,"interference_attenuation");
|
||||||
|
conf=rmfield(conf,"symbolrate");
|
||||||
|
conf=rmfield(conf,"pam_level");
|
||||||
|
|
||||||
% Define vector parameters directly in conf:
|
% Define vector parameters directly in conf:
|
||||||
conf.unique_elab_id = "20250408-842b0a3078172b48dd032795226fbe683190afc4";
|
conf.unique_elab_id = "20250408-842b0a3078172b48dd032795226fbe683190afc4";
|
||||||
conf.db_mode = db_mode.no_db;
|
conf.db_mode = db_mode.no_db;
|
||||||
conf.pulsef_alpha = 0.2;
|
conf.pulsef_alpha = 0.2;
|
||||||
conf.v_bias = 2.65;
|
conf.v_bias = 2.65;
|
||||||
conf.v_awg = 0.9;
|
conf.v_awg = 0.85;
|
||||||
conf.precomp_amp = -64; %-64
|
conf.precomp_amp = -64; %-64
|
||||||
conf.wavelength = 1310;
|
conf.wavelength = 1310;
|
||||||
conf.laser_power = 11;
|
conf.laser_power = 11;
|
||||||
conf.fiber_length = 0;
|
conf.fiber_length = 0;
|
||||||
conf.pd_in_desired = 9;
|
conf.pd_in_desired = 9;
|
||||||
conf.is_mpi = 1;
|
conf.is_mpi = true;
|
||||||
conf.signal_attenuation = 0;
|
conf.signal_attenuation = 0;
|
||||||
conf.interference_path_length = 300; %m
|
conf.interference_path_length = 20; %m
|
||||||
conf.interference_attenuation = [0:2:30,40];
|
conf.interference_attenuation = 10;%[0:2:30,40];
|
||||||
conf.pam_level = [4,6,8];
|
conf.pam_level = 4;%[2,4,6,8];
|
||||||
conf.symbolrate = [56,72,96,112].*1e9;
|
conf.symbolrate = [112].*1e9;
|
||||||
conf.bitrate = conf.symbolrate .* floor(log2(6)*10)/10;
|
|
||||||
conf.pam_source = [];
|
conf.pam_source = [];
|
||||||
|
|
||||||
if conf.is_mpi
|
if conf.is_mpi
|
||||||
current_folder = ['mpi_',num2str(conf.interference_path_length),'m_pam',num2str(conf.pam_level)];
|
current_folder = ['test_mpi_opti_',num2str(conf.interference_path_length),'m_pam',num2str(conf.pam_level)];
|
||||||
else
|
else
|
||||||
current_folder = 'testing';
|
current_folder = 'testing';
|
||||||
end
|
end
|
||||||
@@ -106,10 +109,23 @@ else
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fprintf('Running measurement: %s\n', strjoin(paramDisplayCell, ', '));
|
fprintf('Running measurement: %s ---> %d of %d done \n ', strjoin(paramDisplayCell, ', '),runIdx, totalRuns);
|
||||||
|
|
||||||
|
if confRequest.pam_level == 2
|
||||||
|
confRequest.symbolrate = 112e9;
|
||||||
|
elseif confRequest.pam_level == 4
|
||||||
|
confRequest.symbolrate = 112e9;
|
||||||
|
elseif confRequest.pam_level == 6
|
||||||
|
confRequest.symbolrate = 96e9;
|
||||||
|
elseif confRequest.pam_level == 8
|
||||||
|
confRequest.symbolrate = 72e9;
|
||||||
|
end
|
||||||
|
|
||||||
confRequest.bitrate = confRequest.symbolrate * floor(log2(confRequest.pam_level) * 10) / 10;
|
confRequest.bitrate = confRequest.symbolrate * floor(log2(confRequest.pam_level) * 10) / 10;
|
||||||
% measure_run("config",confRun,"parallel",parallel_dsp,"max_occurences",max_occurences);
|
% measure_run("config",confRun,"parallel",parallel_dsp,"max_occurences",max_occurences);
|
||||||
measure_run_script;
|
|
||||||
|
measure_run_script;
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user