diff --git a/projects/ECOC_2025/dsp_filtered_db.m b/projects/ECOC_2025/dsp_filtered_db.m new file mode 100644 index 0000000..2d832ff --- /dev/null +++ b/projects/ECOC_2025/dsp_filtered_db.m @@ -0,0 +1,68 @@ +% === SETTINGS === +savePath = 'Z:\2025\ECOC Silas\ecoc_2025\'; +% databasePath = '\\ntserver.tf.uni-kiel.de\scratch\sioe\ECOC_2025\'; +databasePath = 'Z:\2025\ECOC Silas\'; + +databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\'; +database_name = 'ecoc2025_loops.db'; +db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite"); + +num_occ = 30; +run_par = true; +refreshInterval = 300; % seconds + +% In-memory list of currently processing run_ids +% currentlyProcessing = []; +alreadyProcessing = []; +fprintf('--- DSP WATCHDOG STARTED ---\n'); + +while true + try + % Query incomplete run_ids + sql_query = [ + 'SELECT ru.run_id ' ... + 'FROM Runs ru ' ... + 'LEFT JOIN Results r ON ru.run_id = r.run_id ' ... + 'LEFT JOIN EqualizerParameters e ON r.eqParam_id = e.eq_id ' ... + 'WHERE ru.loop_id IN ( ' ... + ' SELECT loop_id FROM Runs GROUP BY loop_id HAVING COUNT(*) > 2 ' ... + ') ' ... + 'GROUP BY ru.run_id ' ... + 'HAVING COUNT(CASE WHEN e.equalizer_structure = 1 THEN 1 END) < 5;' + ]; + + runIdsFiltered = db.fetch(sql_query); + newRunIds = setdiff(runIdsFiltered.run_id, alreadyProcessing); + + fprintf('[%s] Found %d run(s) needing processing, %d new.\n', ... + datestr(now, 'yyyy-mm-dd HH:MM:SS'), numel(runIdsFiltered.run_id), numel(newRunIds)); + + for i = 1:numel(newRunIds) + cur_id = newRunIds(i); + + % Add to in-memory processing list + alreadyProcessing(end+1) = cur_id; + + % Submit processing + try + [output, future] = submit_dsp(cur_id, databasePath, database_name, savePath, ... + "parallel", run_par, "max_occurences", num_occ); + + % Add a listener for future completion (success or failure) + + catch err + warning('Error processing run_id %d: %s', cur_id, err.message); + + % Remove from in-memory list even on error (optional: you could leave it for retry) + alreadyProcessing(alreadyProcessing == cur_id) = []; + end + end + + catch err + warning('Error in DSP queue watchdog: %s', err.message); + end + + fprintf('Sleeping for %.0f seconds...\n\n', refreshInterval); + pause(refreshInterval); +end + diff --git a/projects/ECOC_2025/dsp_run_id.m b/projects/ECOC_2025/dsp_run_id.m index fb9f689..37e4106 100644 --- a/projects/ECOC_2025/dsp_run_id.m +++ b/projects/ECOC_2025/dsp_run_id.m @@ -5,14 +5,15 @@ arguments options.append_to_db = 0; options.max_occurences = 4; options.parameters = struct(); - + options.database_path - options.database_name + options.database_name options.storage_path end -database = DBHandler("pathToDB",[options.database_path,options.database_name]); +database = DBHandler("pathToDB",[options.database_path,options.database_name],"type","sqlite"); +% database = DBHandler("type","mysql"); filterParams = database.tables; filterParams.Configurations = struct('run_id', run_id); @@ -47,6 +48,12 @@ mu_ffe3 = 0.001; mu_dfe = 0.0004; mu_dc = 0.00; +% mu_ffe1 = 0; +% mu_ffe2 = 0; +% mu_ffe3 = 0; +% mu_dfe =0; +% mu_dc = 0.00; + mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3]; vnle_order=[vnle_order1,vnle_order2,vnle_order3]; @@ -129,76 +136,83 @@ for occ = 1:record_realizations Scpe_sig = Scpe_sig - mean(Scpe_sig.signal); if duob_mode ~= db_mode.db_encoded - + + vnle_pf = 1; + dbtgt = 0; % %%%%% VNLE + DFE %%%% if 0 - + eq_vnle_dfe = EQ("Ne",vnle_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0); - + [result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,"showAnalysis",1,"postFFE",[]); vnle_dfe_package{occ} = result; - + end - + %%%%% 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); vnle_pf_package{occ} = result; - + if options.append_to_db database.addProcessingResult(run_id,result.resultsMLSE, result.equalizerConfigMLSE); database.addProcessingResult(run_id,result.resultsVNLE, result.equalizerConfigVNLE); end end - + %%%%% Duobinary Targeting %%%% - if 1 + if dbtgt [result] = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode,'showAnalysis',0,"postFFE",[]); dbtgt_package{occ} = result; - + if options.append_to_db database.addProcessingResult(run_id, result.resultsDBtgt, result.equalizerConfigDBtgt); end end - % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e; BER DB tgt: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded,dbtgt_package{occ}.resultsDBtgt.BER,dbtgt_package{occ}.resultsDBtgt.BER_precoded) - % % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded); + % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e; BER DB tgt: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded,dbtgt_package{occ}.resultsDBtgt.BER,dbtgt_package{occ}.resultsDBtgt.BER_precoded) + % % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded); - occ = 1; % or whatever your loop index is + if vnle_pf + occ = 1; % or whatever your loop index is - % Extract VNLE results for readability - vnle = vnle_pf_package{occ}.resultsVNLE; - mlse = vnle_pf_package{occ}.resultsMLSE; - dbtgt = dbtgt_package{occ}.resultsDBtgt; - - % Print header - fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9); - - % VNLE Results - fprintf(">> VNLE Results:\n"); - fprintf(" BER %.2e\n", vnle.BER); - fprintf(" BER (pre-code) %.2e\n", vnle.BER_precoded); - fprintf(" SNR: %.2f dB\n", vnle.SNR); - fprintf(" GMI: %.4f\n", vnle.GMI); - fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9); - fprintf(" AIR: %.2f Gbps\n", vnle.AIR.*1e-9); - fprintf("\n"); - - % MLSE Results - fprintf(">> MLSE Results:\n"); - fprintf(" BER : %.2e\n", mlse.BER); - fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded); - fprintf(" Channel Alpha : %.2f\n", mlse.Alpha); - fprintf("\n"); - - % DB Target Results - fprintf(">> DB Target Results:\n"); - fprintf(" BER: %.2e\n", dbtgt.BER); - fprintf(" BER (pre-code): %.2e\n", dbtgt.BER_precoded); - fprintf("\n"); - + + % Extract VNLE results for readability + vnle = vnle_pf_package{occ}.resultsVNLE; + mlse = vnle_pf_package{occ}.resultsMLSE; + + + % Print header + fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9); + + % VNLE Results + fprintf(">> VNLE Results:\n"); + fprintf(" BER %.2e\n", vnle.BER); + fprintf(" BER (pre-code) %.2e\n", vnle.BER_precoded); + fprintf(" SNR: %.2f dB\n", vnle.SNR); + fprintf(" GMI: %.4f\n", vnle.GMI); + fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9); + fprintf(" AIR: %.2f Gbps\n", vnle.AIR.*1e-9); + fprintf("\n"); + + % MLSE Results + fprintf(">> MLSE Results:\n"); + fprintf(" BER : %.2e\n", mlse.BER); + fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded); + fprintf(" Channel Alpha : %.2f\n", mlse.Alpha); + fprintf("\n"); + end + + if dbtgt + dbtgt = dbtgt_package{occ}.resultsDBtgt; + % DB Target Results + fprintf(">> DB Target Results:\n"); + fprintf(" BER: %.2e\n", dbtgt.BER); + fprintf(" BER (pre-code): %.2e\n", dbtgt.BER_precoded); + fprintf("\n"); + end else diff --git a/projects/ECOC_2025/dsp_standalone.m b/projects/ECOC_2025/dsp_standalone.m index 6424498..3480784 100644 --- a/projects/ECOC_2025/dsp_standalone.m +++ b/projects/ECOC_2025/dsp_standalone.m @@ -1,10 +1,12 @@ -databasePath = 'Z:\2025\ECOC Silas\'; +savePath = 'Z:\2025\ECOC Silas\ecoc_2025\'; +databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\'; database_name = 'ecoc2025_loops.db'; -db = DBHandler("pathToDB", [databasePath, database_name]); +db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite"); +% db = DBHandler("type","mysql"); num_occ = 1; run_par = false; -run_id = 562; -[out, ~] = submit_dsp(run_id, basePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ); +run_id = 2589; +[out, ~] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ); diff --git a/projects/ECOC_2025/load_signal_standalone.m b/projects/ECOC_2025/load_signal_standalone.m new file mode 100644 index 0000000..51ae8bd --- /dev/null +++ b/projects/ECOC_2025/load_signal_standalone.m @@ -0,0 +1,46 @@ + + +run_id = 231; + +savePath = 'Z:\2025\ECOC Silas\ecoc_2025\'; +databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\'; +database_name = 'ecoc2025_loops.db'; +db = DBHandler("type","mysql"); +% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite"); + +filterParams = db.tables; +filterParams.Configurations = struct('run_id', run_id); + +selectedFields = {'Runs.run_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',... + 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',... + 'Configurations.interference_attenuation'}; + +[dataTable,sql_query] = db.queryDB(filterParams, selectedFields); + +[~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices +dataTable = dataTable(uniqueIdx,:); % Extract unique configurations for each run_id + +fsym = dataTable.symbolrate; +M = double(dataTable.pam_level); +duob_mode = db_mode.(strrep(char(dataTable.db_mode),'"','')); + +Tx_signal = load([savePath, char(dataTable.tx_signal_path)]); +Tx_signal = Tx_signal.Digi_sig; + +Tx_bits = load([savePath, char(dataTable.tx_bits_path)]); +Tx_bits = Tx_bits.Bits; +Symbols_mapped = PAMmapper(M,0).map(Tx_bits); +Symbols_mapped.fs = dataTable.symbolrate; + +Symbols = load([savePath, char(dataTable.tx_symbols_path)]); +Symbols = Symbols.Symbols; + +Scpe_sig_raw = load([savePath, char(dataTable.rx_raw_path(1))]); +Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw; +Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",Scpe_sig_raw.fs,"fs_out",2*fsym); +[~,Scpe_cell,found_sync,~,shifts] = Scpe_sig_resampled.tsynch("reference",Symbols,"fs_ref",dataTable.symbolrate,"debug_plots",1); + +shifts_mus = shifts./Scpe_sig_resampled.fs .*1e6; +Scpe_sig_raw.plot("displayname",['Scope Signal (Run ID: ',num2str(run_id)],"fignum",2024,"clear",1); +hold on; +xline(shifts_mus,'HandleVisibility','off'); \ No newline at end of file