updates from lab pc during ecoc sprint

This commit is contained in:
Silas Labor Zizou
2025-04-16 09:18:18 +02:00
parent 0236103b13
commit 943677ee40
9 changed files with 324 additions and 136 deletions

View File

@@ -226,7 +226,7 @@ classdef AwgKeysight
case awg_model.M8199A case awg_model.M8199A
v = visadev('TCPIP0::Zizou::hislip2::INSTR'); v = visadev('TCPIP0::Zizou::hislip2::INSTR');
case awg_model.M8199A_ILV case awg_model.M8199A_ILV
v = visadev('TCPIP0::Zizou::hislip2::INSTR'); v = visadev('TCPIP0::Zizou::hislip0::INSTR');
end end
debug = 0; debug = 0;

View File

@@ -9,6 +9,7 @@ classdef DBHandler < handle
tableNames % Cell array containing names of all tables in the database tableNames % Cell array containing names of all tables in the database
tables = struct(); % Structure containing MATLAB tables for each database table tables = struct(); % Structure containing MATLAB tables for each database table
distinctValues distinctValues
type
end end
methods methods
@@ -21,6 +22,7 @@ classdef DBHandler < handle
arguments arguments
options.pathToDB = ""; % Default value for pathToDB if not provided options.pathToDB = ""; % Default value for pathToDB if not provided
options.type = "mysql";
end end
% Assign values to class properties based on input arguments % Assign values to class properties based on input arguments
@@ -33,7 +35,22 @@ classdef DBHandler < handle
% Establish a connection to the SQLite database % Establish a connection to the SQLite database
try try
if options.type == "sqlite"
obj.conn = sqlite(obj.pathToDB); obj.conn = sqlite(obj.pathToDB);
elseif options.type == "mysql"
datasource = "jdbc:mysql://134.245.243.254:3306/labor";
obj.conn = database( ...
"labor", ... % Database name
"silas", ... % Username
"silas", ... % Password (or getSecret)
"Vendor", "MySQL", ...
"Server", "134.245.243.254", ...
"PortNumber", 3306, ...
"JDBCDriverLocation", "C:\Users\sioe\Documents\mysql-connector-j-9.3.0\mysql-connector-j-9.3.0.jar");
end
catch e catch e
error('Failed to connect to the database: %s', e.message); error('Failed to connect to the database: %s', e.message);
end end
@@ -59,8 +76,14 @@ classdef DBHandler < handle
function obj = getTableNames(obj) function obj = getTableNames(obj)
% Get all table names from the database % Get all table names from the database
try try
if obj.type == "mysql"
result = fetch(obj.conn, 'SHOW TABLES;');
obj.tableNames = result.Variables;
elseif obj.type == "sqlite"
result = fetch(obj.conn, 'SELECT name FROM sqlite_master WHERE type="table"'); result = fetch(obj.conn, 'SELECT name FROM sqlite_master WHERE type="table"');
obj.tableNames = result.name; obj.tableNames = result.name;
end
catch e catch e
error('Failed to retrieve table names: %s', e.message); error('Failed to retrieve table names: %s', e.message);
end end
@@ -213,12 +236,16 @@ classdef DBHandler < handle
elseif ischar(value) elseif ischar(value)
newRow.(colName{1}) = string(value); newRow.(colName{1}) = string(value);
elseif isdatetime(value)
% newRow.(colName{1}) = string(value);
end end
end end
% Parameters for retry logic % Parameters for retry logic
maxRetries = 5; maxRetries = 50;
basePause = 0.05; % seconds basePause = 0.05; % seconds
attempt = 0; attempt = 0;
@@ -226,6 +253,9 @@ classdef DBHandler < handle
while ~success && attempt <= maxRetries while ~success && attempt <= maxRetries
try try
if obj.type == "mysql"
newRow_ = obj.convertTableToCellStrings(newRow);
end
sqlwrite(obj.conn, tableName, newRow); sqlwrite(obj.conn, tableName, newRow);
success = true; % Write successful success = true; % Write successful
catch e catch e
@@ -245,7 +275,14 @@ classdef DBHandler < handle
end end
% Retrieve the measurement_id of the newly inserted row for linking other tables % Retrieve the measurement_id of the newly inserted row for linking other tables
result = fetch(obj.conn, 'SELECT last_insert_rowid()');
if obj.type == "mysql"
queue = "SELECT LAST_INSERT_ID()";
elseif obj.type == "sqlite"
queue = "SELECT last_insert_rowid()";
end
result = fetch(obj.conn, queue);
lastID = result{1, 1}; % Access the value directly from the table lastID = result{1, 1}; % Access the value directly from the table
end end
@@ -502,8 +539,87 @@ classdef DBHandler < handle
% Step 4: Execute the query and handle results % Step 4: Execute the query and handle results
result = obj.fetch(query); result = obj.fetch(query);
result = obj.normalizeMySQLTable(result);
end end
function cleanedTable = normalizeMySQLTable(~,result)
cleanedTable = result;
varNames = result.Properties.VariableNames;
for i = 1:numel(varNames)
col = result.(varNames{i});
% Only process if column is a cell array of strings or chars
if iscell(col) && all(cellfun(@(x) ischar(x) || isstring(x), col))
% Try converting to numeric if possible
numCol = str2double(col);
if all(~isnan(numCol) | strcmpi(col, 'NaN'))
% It's numeric (with possible NaNs)
cleanedTable.(varNames{i}) = numCol;
else
% Clean double-quoted SQL literals (e.g., ""no_db"")
cleanedTable.(varNames{i}) = strrep(string(col), '""', '"');
end
end
end
end
function cellTable = convertTableToCellStrings(~,tbl)
% Converts all variables in a MATLAB table to cell arrays of strings (like JDBC fetch from MySQL)
%
% Example:
% jdbcFormatted = convertTableToCellStrings(myTable);
cellTable = tbl;
varNames = tbl.Properties.VariableNames;
for i = 1:numel(varNames)
col = tbl.(varNames{i});
if isnumeric(col)
% Convert numeric values to strings
cellTable.(varNames{i}) = arrayfun(@(x) num2str(x, '%.15g'), col, 'UniformOutput', false);
elseif isstring(col) || ischar(col)
% Ensure cell array of strings
cellTable.(varNames{i}) = cellstr(col);
elseif iscell(col)
% Convert each cell entry to string
cellTable.(varNames{i}) = cellfun(@convertToString, col, 'UniformOutput', false);
elseif islogical(col)
% Convert logicals to '0' or '1'
cellTable.(varNames{i}) = cellstr(string(double(col)));
elseif isdatetime(col)
% Convert datetimes to formatted string
cellTable.(varNames{i}) = cellstr(string(col));
else
warning('Column "%s" has unsupported type. Converting using string().', varNames{i});
cellTable.(varNames{i}) = cellstr(string(col));
end
end
end
function out = convertToString(~,val)
if ischar(val)
out = val;
elseif isstring(val)
out = char(val);
elseif isnumeric(val)
out = num2str(val, '%.15g');
elseif islogical(val)
out = num2str(double(val));
elseif isdatetime(val)
out = datestr(val, 'yyyy-mm-dd HH:MM:SS');
else
out = char(string(val)); % fallback
end
end
function query = constructSQLQuery(obj, filterParams, selectedFields) function query = constructSQLQuery(obj, filterParams, selectedFields)
% constructSQLQuery Constructs the SQL query based on filter parameters and selected fields. % constructSQLQuery Constructs the SQL query based on filter parameters and selected fields.
% %

View File

@@ -15,7 +15,7 @@ function holdAndShowValue()
'ButtonPushedFcn', @(src, event) closeWindow()); 'ButtonPushedFcn', @(src, event) closeWindow());
% Initialize the timer % Initialize the timer
updateTimer = timer('ExecutionMode', 'fixedRate', 'Period', 0.1, ... updateTimer = timer('ExecutionMode', 'fixedRate', 'Period', 0.5, ...
'TimerFcn', @(src, event) updatePowerValues()); 'TimerFcn', @(src, event) updatePowerValues());
% Start the timer % Start the timer

View File

@@ -12,7 +12,7 @@ arguments
options.storage_path options.storage_path
end end
database = DBHandler("pathToDB",[options.database_path,options.database_name]); database = DBHandler("pathToDB",[options.database_path,options.database_name],"type",'mysql');
filterParams = database.tables; filterParams = database.tables;
filterParams.Configurations = struct('run_id', run_id); filterParams.Configurations = struct('run_id', run_id);
@@ -74,6 +74,9 @@ vnle_pf_package = {};
vnle_dfe_package = {}; vnle_dfe_package = {};
dbtgt_package = {}; dbtgt_package = {};
vnle_pf =1;
db_tgt = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Tx_signal = load([options.storage_path, char(dataTable.tx_signal_path)]); Tx_signal = load([options.storage_path, char(dataTable.tx_signal_path)]);
@@ -142,7 +145,7 @@ for occ = 1:record_realizations
end end
%%%%% VNLE + PF + MLSE %%%% %%%%% VNLE + PF + MLSE %%%%
if 1 if vnle_pf
[result] = vnle_postfilter_mlse(eq_,pf_,mlse_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0); [result] = vnle_postfilter_mlse(eq_,pf_,mlse_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0);
vnle_pf_package{occ} = result; vnle_pf_package{occ} = result;
@@ -154,7 +157,7 @@ for occ = 1:record_realizations
end end
%%%%% Duobinary Targeting %%%% %%%%% Duobinary Targeting %%%%
if 1 if db_tgt
[result] = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode,'showAnalysis',0,"postFFE",[]); [result] = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode,'showAnalysis',0,"postFFE",[]);
dbtgt_package{occ} = result; dbtgt_package{occ} = result;
@@ -168,14 +171,17 @@ for occ = 1:record_realizations
occ = 1; % or whatever your loop index is occ = 1; % or whatever your loop index is
if vnle_pf
% Extract VNLE results for readability % Extract VNLE results for readability
vnle = vnle_pf_package{occ}.resultsVNLE; vnle = vnle_pf_package{occ}.resultsVNLE;
mlse = vnle_pf_package{occ}.resultsMLSE; mlse = vnle_pf_package{occ}.resultsMLSE;
end
if db_tgt
dbtgt = dbtgt_package{occ}.resultsDBtgt; dbtgt = dbtgt_package{occ}.resultsDBtgt;
end
% Print header % Print header
fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9); fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9);
if vnle_pf
% VNLE Results % VNLE Results
fprintf(">> VNLE Results:\n"); fprintf(">> VNLE Results:\n");
fprintf(" BER %.2e\n", vnle.BER); fprintf(" BER %.2e\n", vnle.BER);
@@ -192,13 +198,14 @@ for occ = 1:record_realizations
fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded); fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded);
fprintf(" Channel Alpha : %.2f\n", mlse.Alpha); fprintf(" Channel Alpha : %.2f\n", mlse.Alpha);
fprintf("\n"); fprintf("\n");
end
if db_tgt
% DB Target Results % DB Target Results
fprintf(">> DB Target Results:\n"); fprintf(">> DB Target Results:\n");
fprintf(" BER: %.2e\n", dbtgt.BER); fprintf(" BER: %.2e\n", dbtgt.BER);
fprintf(" BER (pre-code): %.2e\n", dbtgt.BER_precoded); fprintf(" BER (pre-code): %.2e\n", dbtgt.BER_precoded);
fprintf("\n"); fprintf("\n");
end
else else

View File

@@ -1,10 +1,10 @@
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
databasePath = 'Z:\2025\ECOC Silas\'; databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
database_name = 'ecoc2025_loops.db'; database_name = 'ecoc2025_loops.db';
db = DBHandler("pathToDB", [databasePath, database_name]);
num_occ = 1; num_occ = 1;
run_par = false; run_par = false;
run_id = 562; run_id = 2589;
[out, ~] = submit_dsp(run_id, basePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ); [out, ~] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ);

View File

@@ -1,7 +1,5 @@
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
fullFolderPath = fullfile(savePath, current_folder); fullFolderPath = fullfile(savePath, current_folder);
if ~exist(fullFolderPath, 'dir') if ~exist(fullFolderPath, 'dir')
mkdir(fullFolderPath); mkdir(fullFolderPath);
@@ -19,19 +17,19 @@ 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
if run_lab_automation if run_lab_automation
% DC Source % DC Source
if confPrev.v_bias ~= conf.v_bias if (any(confPrev.v_bias ~= conf.v_bias)) || (~exist('dcs','var')) || (isempty(confPrev.v_bias))
dcs = DC_supply("active",[1,1],"voltage",[conf.v_bias, 5]); dcs = DC_supply("active",[1,1],"voltage",[conf.v_bias, 5]);
dcs.set("voltage",[conf.v_bias, 5]); dcs.set("voltage",[conf.v_bias, 5]);
[v_bias_meas,i_bias_meas]=dcs.readVals(); [v_bias_meas,i_bias_meas]=dcs.readVals();
end end
% Laser % Laser
if confPrev.laser_power ~= conf.laser_power
if (any(confPrev.laser_power ~= conf.laser_power)) || (~exist('laser','var')) || (isempty(confPrev.laser_power))
laser = Exfo_laser("mainframe_channel",1,"safety_mode",0,"connection_id",'10','lab_interface','gpib'); laser = Exfo_laser("mainframe_channel",1,"safety_mode",0,"connection_id",'10','lab_interface','gpib');
laser.setWavelength(conf.wavelength); laser.setWavelength(conf.wavelength);
laser.setPower(conf.laser_power); laser.setPower(conf.laser_power);
@@ -39,16 +37,24 @@ if run_lab_automation
end end
% Optical Attenuator % Optical Attenuator
voa = OptAtten("active",[0,2,1,1],"value",[0,conf.pd_in_desired,conf.signal_attenuation,conf.interference_attenuation],"wavelength",[conf.wavelength,conf.wavelength,conf.wavelength,conf.wavelength]); if ~exist('voa','var')
voa = OptAtten("active",[1,2,1,1],"value",[0,conf.pd_in_desired,conf.signal_attenuation,conf.interference_attenuation],"wavelength",[conf.wavelength,conf.wavelength,conf.wavelength,conf.wavelength]);
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
holdAndShowValue
end
% PDFA % PDFA
if ~exist('pdfa','var')
pdfa = Thor_PDFA("safety_mode",0,"serialport_number",'COM15'); pdfa = Thor_PDFA("safety_mode",0,"serialport_number",'COM15');
end
% Construct AWG and Scope Modules %%%%%% % Construct AWG and Scope Modules %%%%%%
fdac = 224e9; fdac = 224e9;
fadc = 160e9; fadc = 160e9;
Scp = ScopeKeysight("model","DSAZ634A",'autoscale',1,"fadc","GSa_160","channel",[0,0,1,0],"recordLen",5000000,"removeDC",1,"extRef",1); 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]); 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); A2S = Awg2Scope(Awg,Scp,[0,0,3,0],"waitUntilClick",0);
@@ -56,12 +62,16 @@ end
%% Signal generation and transmission %% Signal generation and transmission
if 0% awg_upload_required || isempty(loop_id) if awg_upload_required || isempty(loop_id)
%%%%% Symbol Generation %%%%%% %%%%% Symbol Generation %%%%%%
Pform = Pulseformer("fsym",conf.symbolrate,"fdac",8*conf.symbolrate,"pulse","rc","pulselength",16,"alpha",conf.pulsef_alpha); Pform = Pulseformer("fsym",conf.symbolrate,"fdac",8*conf.symbolrate,"pulse","rc","pulselength",16,"alpha",conf.pulsef_alpha);
if conf.symbolrate < 64e9
sequence_order = min(18,sequence_order);
end
Pamsource = PAMsource(... Pamsource = PAMsource(...
"fsym",conf.symbolrate,"M",conf.pam_level,"order",19,"useprbs",1,... "fsym",conf.symbolrate,"M",conf.pam_level,"order",sequence_order,"useprbs",1,...
"fs_out",fdac,... "fs_out",fdac,...
"applyclipping",0,... "applyclipping",0,...
"clipfactor",4,... "clipfactor",4,...
@@ -104,7 +114,6 @@ if precomp_mode == 1
return; % End routine if precomp mode is active return; % End routine if precomp mode is active
end end
%% 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);
@@ -119,8 +128,6 @@ save([savePath, tx_symbols_path], "Symbols");
tx_signal_path = [filesep, current_folder, filesep, base_filename, '_signal']; tx_signal_path = [filesep, current_folder, filesep, base_filename, '_signal'];
save([savePath, tx_signal_path], "Digi_sig"); save([savePath, tx_signal_path], "Digi_sig");
n_recording = 2; % Or any number you want
for recIdx = 1:n_recording for recIdx = 1:n_recording
fprintf('Recording %d / %d\n', recIdx, n_recording); fprintf('Recording %d / %d\n', recIdx, n_recording);
@@ -167,7 +174,7 @@ for recIdx = 1:n_recording
newRun.date_of_run = datetime(currentTime, 'InputFormat', 'yyyyMMdd_HHmmss'); newRun.date_of_run = datetime(currentTime, 'InputFormat', 'yyyyMMdd_HHmmss');
newRun.tx_bits_path = tx_bits_path; newRun.tx_bits_path = tx_bits_path;
newRun.tx_symbols_path = tx_symbols_path; newRun.tx_symbols_path = tx_symbols_path;
newRun.rx_sync_path = []; % Leave empty for now newRun.rx_sync_path = ""; % Leave empty for now
newRun.rx_raw_path = rx_raw_path; newRun.rx_raw_path = rx_raw_path;
newRun.filename = filename; newRun.filename = filename;
newRun.tx_signal_path = tx_signal_path; newRun.tx_signal_path = tx_signal_path;
@@ -197,10 +204,12 @@ for recIdx = 1:n_recording
db.appendToTable('Measurements', meas); db.appendToTable('Measurements', meas);
%% Submit DSP Routine %% Submit DSP Routine
% [out, ~] = submit_dsp(run_id, basePath, database_name, savePath, ... if subimt_DSP
% "parallel", parallel_dsp, "max_occurences", max_occurences); [out, a] = submit_dsp(run_id, databasePath, database_name, savePath, ...
"parallel", parallel_dsp, "max_occurences", max_occurences);
end
end end

View File

@@ -1,8 +1,20 @@
local = 1;
if local
databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
else
databasePath = '\\ntserver.tf.uni-kiel.de\scratch\sioe\ECOC_2025\';
end
basePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
database_name = 'ecoc2025_loops.db'; database_name = 'ecoc2025_loops.db';
database = DBHandler("pathToDB", [basePath, database_name]); database = DBHandler("pathToDB", [databasePath, database_name]);
figure();
plotBoundaries = 1;
plotRealizations = 1;
cols = linspecer(3); % Ensure color count matches
% cols = cols(8,:);
filterParams = database.tables; filterParams = database.tables;
filterParams.Configurations = struct( ... filterParams.Configurations = struct( ...
@@ -10,7 +22,7 @@ filterParams.Configurations = struct( ...
'fiber_length', 0, ... 'fiber_length', 0, ...
'db_mode', '"no_db"', ... 'db_mode', '"no_db"', ...
'interference_attenuation', [], ... 'interference_attenuation', [], ...
'interference_path_length', 50, ... 'interference_path_length', 10, ...
'is_mpi', 1, ... 'is_mpi', 1, ...
'pam_level', 4, ... 'pam_level', 4, ...
'wavelength', 1310, ... 'wavelength', 1310, ...
@@ -23,8 +35,8 @@ filterParams.Configurations = struct( ...
% filterParams.EqualizerParameters.diff_precode = int32(db_mode.db_encoded); % filterParams.EqualizerParameters.diff_precode = int32(db_mode.db_encoded);
% filterParams.EqualizerParameters.equalizer_structure = int32(equalizer_structure.vnle); % filterParams.EqualizerParameters.equalizer_structure = int32(equalizer_structure.vnle);
selectedFields = {'Configurations.run_id' 'Runs.date_of_run' 'Runs.rx_raw_path' 'Configurations.bitrate' 'Configurations.v_bias' 'Configurations.v_awg' 'Configurations.precomp_amp' 'Configurations.symbolrate' 'Configurations.pam_level'... selectedFields = {'Configurations.run_id' 'Runs.loop_id' 'Runs.date_of_run' 'Runs.rx_raw_path' 'Configurations.bitrate' 'Configurations.v_bias' 'Configurations.v_awg' 'Configurations.precomp_amp' 'Configurations.symbolrate' 'Configurations.pam_level'...
'Configurations.db_mode' 'Configurations.rop_attenuation' 'Configurations.is_mpi' 'Configurations.interference_attenuation' 'Configurations.signal_attenuation' ... 'Configurations.db_mode' 'Configurations.rop_attenuation' 'Configurations.is_mpi' 'Configurations.interference_attenuation' 'Configurations.interference_path_length' 'Configurations.signal_attenuation' ...
'EqualizerParameters.equalizer_structure' 'EqualizerParameters.diff_precode' 'EqualizerParameters.eq_id' 'Measurements.power_pd_in' ... 'EqualizerParameters.equalizer_structure' 'EqualizerParameters.diff_precode' 'EqualizerParameters.eq_id' 'Measurements.power_pd_in' ...
'Measurements.power_mpi_interference' 'Measurements.power_mpi_signal' 'Results.BER' 'Results.BER_precoded' 'Results.SNR' 'Results.GMI' 'Results.Alpha' 'Results.date_of_processing'}; 'Measurements.power_mpi_interference' 'Measurements.power_mpi_signal' 'Results.BER' 'Results.BER_precoded' 'Results.SNR' 'Results.GMI' 'Results.Alpha' 'Results.date_of_processing'};
@@ -32,14 +44,18 @@ selectedFields = {'Configurations.run_id' 'Runs.date_of_run' 'Runs.rx_raw_path'
dataTable.SIR = round(-6 - dataTable.power_mpi_interference); dataTable.SIR = round(-6 - dataTable.power_mpi_interference);
dataTable = cleanUpTable(dataTable); dataTable = cleanUpTable(dataTable);
dataTable(dataTable.eq_id==0,:) = [];
% Filter by time % Filter by time
startTime = datetime('2025-04-12 18:00:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss'); filter_by_time = 0;
stopTime = datetime('2025-04-13 19:30:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss'); if filter_by_time
startTime = datetime('2025-04-14 13:00:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
stopTime = datetime('2025-04-14 19:30:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
dataTable.date_of_run = datetime(dataTable.date_of_run, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS'); dataTable.date_of_run = datetime(dataTable.date_of_run, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
dataTable.date_of_processing = datetime(dataTable.date_of_processing, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS'); dataTable.date_of_processing = datetime(dataTable.date_of_processing, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
dataTable = dataTable(dataTable.date_of_processing > startTime, :); dataTable = dataTable(dataTable.date_of_processing > startTime, :);
dataTable = dataTable(dataTable.date_of_processing < stopTime, :); dataTable = dataTable(dataTable.date_of_processing < stopTime, :);
end
% Group by smth % Group by smth
y_var = 'BER'; y_var = 'BER';
x_var = 'SIR'; x_var = 'SIR';
@@ -53,16 +69,14 @@ dataTableGrpd_mean = groupIt(fixedVars, dataTable, @mean);
dataTableGrpd_min = groupIt(fixedVars, dataTable, @min); dataTableGrpd_min = groupIt(fixedVars, dataTable, @min);
dataTableGrpd_max = groupIt(fixedVars, dataTable, @max); dataTableGrpd_max = groupIt(fixedVars, dataTable, @max);
plotRealizations = 1;
% Create a new figure % Create a new figure
mkr = '.'; mkr = '.';
figure();
hold on hold on
unique_loop_var = unique(dataTable.(loop_var)); unique_loop_var = unique(dataTable.(loop_var));
cols = linspecer(numel(unique_loop_var)); % Ensure color count matches
for i = 1:2%1:numel(unique_loop_var) for i = 1%:numel(unique_loop_var)
% Prepare filtered data for this loop variable % Prepare filtered data for this loop variable
loopValue = unique_loop_var(i); loopValue = unique_loop_var(i);
@@ -86,7 +100,9 @@ for i = 1:2%1:numel(unique_loop_var)
% Display name (optional) % Display name (optional)
idx = find(dataTable.(loop_var) == loopValue, 1, 'first'); idx = find(dataTable.(loop_var) == loopValue, 1, 'first');
dispname = equalizer_structure(dataTable.equalizer_structure(idx)); dispname = equalizer_structure(dataTable.equalizer_structure(idx));
dispname = [char(dispname),'; ',num2str(unique(dataTable.interference_path_length)),' m'];
if plotBoundaries
% Plot bounded line % Plot bounded line
[hl, hp] = boundedline(x_values, y_mean, y_bounds, ... [hl, hp] = boundedline(x_values, y_mean, y_bounds, ...
'alpha', 'transparency', 0.2, ... 'alpha', 'transparency', 0.2, ...
@@ -102,15 +118,20 @@ for i = 1:2%1:numel(unique_loop_var)
set(hp, 'HandleVisibility', 'off','LineStyle',':','LineWidth',0.5,'Marker','none'); set(hp, 'HandleVisibility', 'off','LineStyle',':','LineWidth',0.5,'Marker','none');
% Add invisible scatter for DataTips % Add invisible scatter for DataTips
sc_fake = scatter(x_values, y_mean, ... plt = scatter(x_values, y_mean, ...
'Marker', 'o', 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'none', ... 'Marker', 'o', 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'none', ...
'HandleVisibility', 'off', 'PickableParts', 'all'); 'HandleVisibility', 'off', 'PickableParts', 'all');
else
plt= plot(x_values,y_mean,'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none', ...
'Color', cols(i,:), 'DisplayName', string(dispname));
end
% Add data tips to the invisible scatter % Add data tips to the invisible scatter
pair_one = {'Run ID', dataTableGrpd_mean.run_id(loopFiltGrpd, :)}; pair_one = {'Run ID', dataTableGrpd_mean.run_id(loopFiltGrpd, :)};
pair_two = {'Rate', dataTableGrpd_mean.bitrate(loopFiltGrpd, :) * 1e-9}; pair_two = {'Rate', dataTableGrpd_mean.bitrate(loopFiltGrpd, :) * 1e-9};
pair_three = {'PD in', round(dataTableGrpd_mean.power_pd_in(loopFiltGrpd, :), 2)}; pair_three = {'PD in', round(dataTableGrpd_mean.power_pd_in(loopFiltGrpd, :), 2)};
addDatatips(sc_fake, pair_one, pair_two, pair_three); addDatatips(plt, pair_one, pair_two, pair_three);
% Optionally: outline bounds for better visibility (optional) % Optionally: outline bounds for better visibility (optional)
% hnew = outlinebounds(hl, hp); % hnew = outlinebounds(hl, hp);
@@ -145,6 +166,8 @@ if y_var == 'BER'
ylim([1e-5, 0.1]); ylim([1e-5, 0.1]);
end end
xlim([15,50]);
% Enable grid and beautify % Enable grid and beautify
grid on; grid on;
beautifyBERplot; beautifyBERplot;

View File

@@ -2,23 +2,36 @@
% === Prepare base configuration === % === Prepare base configuration ===
% databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\'; % databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
databasePath = 'Z:\2025\ECOC Silas\'; local = 1;
database_name = 'ecoc2025_loops.db'; if local
db = DBHandler("pathToDB", [databasePath, database_name]); databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
conf = db.tables.Configurations; savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
confPrev = db.tables.Configurations; else
databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
end
awg_upload_required = 0; database_name = 'ecoc2025_loops.db';
db = DBHandler("pathToDB", [databasePath, database_name],"type",'mysql');
conf = db.tables.Configurations;
if ~exist('confPrev','var')
confPrev = db.tables.Configurations;
end
awg_upload_required = 1; %still uploads every first round
subimt_DSP = 1;
recordlen = 5000000;
sequence_order = 17;
n_recording = 1; % Or any number you want
% 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.symbolrate = 112e9;
conf.bitrate = conf.symbolrate .* floor(log2(6)*10)/10;
conf.pam_level = 4;
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.5; conf.v_bias = 2.65;
conf.v_awg = 0.95; conf.v_awg = 0.9;
conf.precomp_amp = -64; %-64 conf.precomp_amp = -64; %-64
conf.wavelength = 1310; conf.wavelength = 1310;
conf.laser_power = 11; conf.laser_power = 11;
@@ -26,8 +39,11 @@ conf.fiber_length = 0;
conf.pd_in_desired = 9; conf.pd_in_desired = 9;
conf.is_mpi = 1; conf.is_mpi = 1;
conf.signal_attenuation = 0; conf.signal_attenuation = 0;
conf.interference_path_length = 1000; %m conf.interference_path_length = 0; %m
conf.interference_attenuation = [40,20:-1:0]; conf.interference_attenuation = 40;%[0:2:30,40];
conf.pam_level = 4;%[4,6,8];
conf.symbolrate = 56e9;%[56,72,96,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

View File

@@ -0,0 +1,17 @@
db = DBHandler("type","mysql");
db.tableNames
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
newRun = db.tables.Runs;
newRun.run_id = NaN;
newRun.loop_id = 82;
newRun.date_of_run = datetime(currentTime, 'InputFormat', 'yyyyMMdd_HHmmss');
newRun.tx_bits_path = 'pathtohell';
newRun.tx_symbols_path = 'pathtohell2';
newRun.rx_sync_path = ""; % Leave empty for now
newRun.rx_raw_path = 'pathtohell4';
newRun.filename = 'filenametohell';
newRun.tx_signal_path = 'pathtohell';
run_id = db.appendToTable('Runs', newRun);