Add new minimal example (+ a ton of other, not so important, changes)

This commit is contained in:
Silas Oettinghaus
2025-12-15 15:04:15 +01:00
parent 75dddca1f2
commit 569e72a1fe
43 changed files with 3594 additions and 674 deletions

View File

@@ -95,11 +95,11 @@ try
adaption= 1;
use_dd_mode = 1;
use_ffe = 1;
use_dfe = 1;
use_vnle_mlse = 1;
use_dbtgt = 1;
use_dbenc = 1;
use_ffe = 0;
use_dfe = 0;
use_vnle_mlse = 0;
use_dbtgt = 0;
use_dbenc = 0;
use_ml_mlse = 1;
addProcessingResultToDatabase = 0;

View File

@@ -130,6 +130,10 @@ db_results.config.equalizer_structure = int32(equalizer_structure.vnle_db_mlse);
db_results.config.comment = 'function: Duobinary tgt. (VNLE -> MLSE)';
if options.showAnalysis
eq_signal.eye(eq_signal.fs,M,"fignum",249);
eq_noise = eq_noise - mean(eq_noise.signal);
rx_signal.spectrum("normalizeTo0dB",1,"fignum",250,"displayname","Rx Spectrum");

View File

@@ -22,7 +22,6 @@ end
% Ensure the figure is ready before calling spectrum
eq_noise.spectrum("displayname", options.displayname, "fignum", fig.Number, "normalizeTo0dB", 1,"color",options.color);
title('EEN')
if ~isnan(options.postfilter_taps)
% Hold on to the figure for further plotting

View File

@@ -52,6 +52,8 @@ end
legend
grid on
% view([90 -90]);
end

View File

@@ -16,13 +16,17 @@ Scpe_sig = Scpe_sig.resample("fs_out", 2*fsym);
[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 0);
% Apply Gaussian filter
if 1
Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*0.52, ...
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
"active", true).process(Scpe_sig);
if 1
Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*0.52, ...
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
"active", true).process(Scpe_sig);
else
Scpe_sig = Filter('filtdegree', 4, "f_cutoff", Symbols.fs.*0.6, ...
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
"active", true).process(Scpe_sig);
end
% Remove DC offset
%Remove DC offset
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
end

View File

@@ -2,11 +2,11 @@
% IM/DD Fading Notch λ_null vs. Bandwidth (Fixed 10 km)
% ============================================================
clear; clc;
%% Fiber and dispersion parameters
lambda0 = 1315e-9; % Zero-dispersion wavelength [m]
S0 = 0.08; % Dispersion slope at ZDW [ps/(nm²·km)]
lambda0 = 1310e-9; % Zero-dispersion wavelength [m]
S0 = 0.09; % Dispersion slope at ZDW [ps/(nm²·km)]
L = 10e3; % Fiber length [m]
c = physconst('lightspeed');
@@ -17,74 +17,73 @@ f_GHz = f_targets / 1e9;
%% Compute wavelength λ_null for each target f_null
[lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_targets, L, lambda0, S0);
lambda_nm = lambda_vec * 1e9; % Convert to nm
Dacc = Dacc_vec; % [ps/nm]
%% ------------------------------------------------------------
% Plot λ_null vs. f_null for 10 km fiber
% ------------------------------------------------------------
% figure('Color','w');
% plot(lambda_nm,f_GHz, 'LineWidth', 2);
% grid on; box on;
cols = cbrewer2('Paired',10);
figure('Color','w');hold on
figure('Color','w'); hold on;
plot(lambda_nm, f_GHz, 'LineWidth',2,'DisplayName',sprintf('%d km',L),'Color',cols(2,:));
hLine = plot(lambda_nm, f_GHz, ...
'LineWidth', 2, ...
'DisplayName', sprintf('L = %.1f km', L/1000), ...
'Color', cols(2,:));
yticks([56,75,90,112])
f_GHz = [56,75,90,112] * 1e9;
[lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_GHz, L, lambda0, S0);
lambda_nm = lambda_vec * 1e9; % Convert to nm
xticks(round(lambda_nm))
xlabel('$\Delta \lambda$ from ZDW [nm]');
ylabel('$F_{null}$ [GHz]');
xlabel('Wavelength λ [nm]');
ylabel('First fading notch f_{null} [GHz]');
title('IM/DD Fading Notch Position vs. Wavelength');
grid on; box on;
lim=(lambda0.*1e9)-[8,40];
lim = (lambda0.*1e9) - [8, 40];
xlim([lim(2) lim(1)]);
% ylim([40,130])
yticks([56,75,90,112]);
%% ------------------------------------------------------------
% Custom DataTip Template
% ------------------------------------------------------------
% Add accumulated dispersion value to the DataTip
hLine.DataTipTemplate.DataTipRows(1).Label = 'λ [nm]';
hLine.DataTipTemplate.DataTipRows(2).Label = 'f_{null} [GHz]';
% Create a new row for Dacc
dRow = dataTipTextRow('D_{acc} [ps/nm]', Dacc);
hLine.DataTipTemplate.DataTipRows(end+1) = dRow;
%% ------------------------------------------------------------
% Helper function: lambda_for_first_null_full
% Stable, single-branch, clamped to O-band
% ------------------------------------------------------------
function [lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_target, L, lambda0, S0)
c = physconst('lightspeed');
S0_si = S0 * 1e3; % ps/(nm²·km) -> s/(m³)
c = physconst('lightspeed');
S0_si = S0 * 1e3; % ps/(nm²·km) -> s/(m³)
% Define O-band boundaries [m]
lambda_min = 1260e-9;
lambda_max = 1360e-9;
lambda_min = 1260e-9;
lambda_max = 1360e-9;
f_target = f_target(:);
N = numel(f_target);
f_target = f_target(:);
N = numel(f_target);
lambda_vec = zeros(N,1);
Dacc_vec = zeros(N,1);
lambda_vec = zeros(N,1);
Dacc_vec = zeros(N,1);
for k = 1:N
RHS = c * 0.5 / (f_target(k)^2 * L);
for k = 1:N
RHS = c * 0.5 / (f_target(k)^2 * L);
% Normal-dispersion branch (λ < λ0)
fun = @(lambda) -(S0_si/4).*(lambda - (lambda0^4)./(lambda.^3)).*lambda.^2 - RHS;
fun = @(lambda) -(S0_si/4).*(lambda - (lambda0^4)./(lambda.^3)).*lambda.^2 - RHS;
% Solve within normal-dispersion range
try
lambda_sol = fzero(fun, [lambda_min, lambda0 * 0.999]);
catch
lambda_sol = lambda_min;
try
lambda_sol = fzero(fun, [lambda_min, lambda0 * 0.999]);
catch
lambda_sol = lambda_min;
end
lambda_sol = min(max(lambda_sol, lambda_min), lambda_max);
lambda_vec(k) = lambda_sol;
D_lambda = (S0_si/4) * (lambda_sol - (lambda0^4)/(lambda_sol^3)) / 1e-6; % ps/(nm·km)
Dacc_val = D_lambda * (L/1000); % ps/nm
Dacc_val = min(max(Dacc_val, -100), 100);
Dacc_vec(k) = Dacc_val;
end
% Clamp to O-band
lambda_sol = min(max(lambda_sol, lambda_min), lambda_max);
lambda_vec(k) = lambda_sol;
% Compute D(lambda) and accumulated dispersion
D_lambda = (S0_si/4) * (lambda_sol - (lambda0^4)/(lambda_sol^3)) / 1e-6; % ps/(nm·km)
Dacc_val = D_lambda * (L/1000); % ps/nm
Dacc_val = min(max(Dacc_val, -100), 100);
Dacc_vec(k) = Dacc_val;
end
end

View File

@@ -11,6 +11,7 @@ function beautifyBERplot(options)
arguments
options.logscale (1,1) logical = 1
options.setmarkers (1,1) logical = 1;
options.polyfit (1,1) logical = 0
options.polyorder (1,1) double = 2
options.fitmethod (1,1) string = "polyfit" % choose fit type
@@ -23,13 +24,15 @@ num_markers = length(markers);
% --- style all lines consistently
for i = 1:length(lines)
lines(i).LineWidth = 1;
lines(i).LineWidth = 1.2;
% lines(i).LineStyle = '-';
if string(lines(i).Marker) == "none"
lines(i).Marker = markers{mod(i-1, num_markers) + 1};
if options.setmarkers == 1
if string(lines(i).Marker) == "none"
lines(i).Marker = markers{mod(i-1, num_markers) + 1};
end
lines(i).MarkerSize = 4;
lines(i).MarkerFaceColor = lines(i).Color;
end
lines(i).MarkerSize = 4;
lines(i).MarkerFaceColor = lines(i).Color;
end
% --- optional smoothing/fitting overlay