ecoc measurements

This commit is contained in:
Silas Labor Zizou
2025-04-13 16:29:12 +02:00
parent 00f1c557c0
commit 0236103b13
19 changed files with 709 additions and 359 deletions

View File

@@ -2,16 +2,11 @@
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
current_folder = 'precomp_optimization_friday';
fullFolderPath = fullfile(savePath, current_folder);
if ~exist(fullFolderPath, 'dir')
mkdir(fullFolderPath);
end
basePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
database_name='ecoc2025.db';
db = DBHandler("pathToDB",[basePath,database_name]);
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_mode = 2; %0=do nothing ; 1= measure; 2=precomp active
@@ -24,9 +19,6 @@ referenceFields = fieldnames(db.tables.Configurations);
assert(isequal(fieldnames(conf), referenceFields), 'Fieldnames do not match the reference structure!');
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
timeStr = char(currentTime);
filename = sprintf('%s_PAM_%d_R_%d',timeStr,conf.pam_level,conf.symbolrate.*1e-9);
%% Lab Automation
@@ -38,7 +30,6 @@ if run_lab_automation
dcs.set("voltage",[conf.v_bias, 5]);
[v_bias_meas,i_bias_meas]=dcs.readVals();
end
% Laser
if confPrev.laser_power ~= conf.laser_power
laser = Exfo_laser("mainframe_channel",1,"safety_mode",0,"connection_id",'10','lab_interface','gpib');
@@ -55,7 +46,7 @@ if run_lab_automation
pdfa = Thor_PDFA("safety_mode",0,"serialport_number",'COM15');
% Construct AWG and Scope Modules %%%%%%
fdac = 256e9;
fdac = 224e9;
fadc = 160e9;
Scp = ScopeKeysight("model","DSAZ634A",'autoscale',1,"fadc","GSa_160","channel",[0,0,1,0],"recordLen",5000000,"removeDC",1,"extRef",1);
Awg = AwgKeysight("model","M8199A_ILV","fdac",fdac,"scaletodac",[1,1],"skews",[0,0],"voltages",[0,conf.v_awg]);
@@ -65,108 +56,151 @@ end
%% Signal generation and transmission
if 0% awg_upload_required || isempty(loop_id)
%%%%% Symbol Generation %%%%%%
Pform = Pulseformer("fsym",conf.symbolrate,"fdac",8*conf.symbolrate,"pulse","rc","pulselength",16,"alpha",conf.pulsef_alpha);
Pamsource = PAMsource(...
"fsym",conf.symbolrate,"M",conf.pam_level,"order",19,"useprbs",1,...
"fs_out",fdac,...
"applyclipping",0,...
"clipfactor",4,...
"applypulseform",1,...
"pulseformer",Pform,...
"randkey",1,...
"duobinary_mode", conf.db_mode);
conf.pam_source = Pamsource;
confPrev = conf;
[Digi_sig,Symbols,Bits] = Pamsource.process();
%%%%% Precompensation Routine %%%%%%
if precomp_mode == 1 % measure channel
precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',fdac);
Digi_sig = precomp_est.buildOFDM();
elseif precomp_mode == 2 % apply precomp
precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',Digi_sig.fs);
Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',conf.precomp_amp,'loadPath',precomp_path,'fileName',precomp_fn);
end
% Digi_sig.spectrum("displayname",'Tx Spectrum','fignum',10,'normalizeTo0dB',0);
%%%%% Resample to DAC rate %%%%%%
Digi_sig = Digi_sig.resample("fs_out",Awg.fdac);
% [~,~,Scpe_sig_raw,~] = A2S.process("signal2",Digi_sig);
%%%%% Symbol Generation %%%%%%
Pform = Pulseformer("fsym",conf.symbolrate,"fdac",8*conf.symbolrate,"pulse","rc","pulselength",16,"alpha",conf.pulsef_alpha);
Pamsource = PAMsource(...
"fsym",conf.symbolrate,"M",conf.pam_level,"order",19,"useprbs",1,...
"fs_out",fdac,...
"applyclipping",0,...
"clipfactor",4,...
"applypulseform",1,...
"pulseformer",Pform,...
"randkey",1,...
"duobinary_mode", conf.db_mode);
conf.pam_source = Pamsource;
upload_required = ~isequal(Pamsource, confPrev.pam_source);
confPrev = conf;
[Digi_sig,Symbols,Bits] = Pamsource.process();
%%%%% Precompensation Routine %%%%%%
if precomp_mode == 1 % measure channel
precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',fdac);
Digi_sig = precomp_est.buildOFDM();
upload_required = 1;
elseif precomp_mode == 2 % apply precomp
precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',Digi_sig.fs);
Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',conf.precomp_amp,'loadPath',precomp_path,'fileName',precomp_fn);
end
Digi_sig.spectrum("displayname",'Tx Spectrum','fignum',10,'normalizeTo0dB',0);
%%%%% Resample to DAC rate %%%%%%
Digi_sig = Digi_sig.resample("fs_out",Awg.fdac);
% [~,~,Scpe_sig_raw,~] = A2S.process("signal2",Digi_sig);
if upload_required || confPrev.v_awg ~= conf.v_awg
Awg.upload("signal2",Digi_sig);
end
Scpe_sig_raw = Scp.read("channel",[0,0,1,0]);
Scpe_sig_raw = Scpe_sig_raw{[0,0,1,0]==1};
%%%%% Precompensation Routine %%%%%%
% Precompensation Routine (optional)
if precomp_mode == 1
% Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",fadc,"fs_out",2*fsym);
precomp_est.estimate(Scpe_sig_raw,"save",true,"savePath",precomp_path,"fileName",precomp_fn);
Scpe_sig_raw = Scp.read("channel",[0,0,1,0]);
Scpe_sig_raw = Scpe_sig_raw{[0,0,1,0]==1};
precomp_est.estimate(Scpe_sig_raw, "save", true, "savePath", precomp_path, "fileName", precomp_fn);
precomp_est.plot();
return;
return; % End routine if precomp mode is active
end
Scpe_sig_raw.spectrum("displayname",'Rx Spectrum','fignum',10,'normalizeTo0dB',0);
Scpe_sig_raw.plot("clear",1,"displayname",'Rx Signal','fignum',11);
%% Save static TX data (only once)
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
timeStr = char(currentTime);
base_filename = sprintf('%s_PAM_%d_R_%d', timeStr, conf.pam_level, round(conf.symbolrate.*1e-9));
%% %%%%% Save Routine %%%%%%%%%%%%%%%%%%%%%%%%%
tx_bits_path = [filesep, current_folder, filesep, base_filename, '_bits'];
save([savePath, tx_bits_path], "Bits");
tx_bits_path=[filesep,current_folder,filesep,filename,'_bits'];
save([savePath,tx_bits_path],"Bits");
tx_symbols_path=[filesep,current_folder,filesep,filename,'_symbols'];
save([savePath,tx_symbols_path],"Symbols");
tx_signal_path=[filesep,current_folder,filesep,filename,'_signal'];
save([savePath,tx_signal_path],"Digi_sig");
rx_raw_path = [filesep,current_folder,filesep,filename,'_rx_signal_raw'];
save([savePath,rx_raw_path],"Scpe_sig_raw");
tx_symbols_path = [filesep, current_folder, filesep, base_filename, '_symbols'];
save([savePath, tx_symbols_path], "Symbols");
tx_signal_path = [filesep, current_folder, filesep, base_filename, '_signal'];
save([savePath, tx_signal_path], "Digi_sig");
n_recording = 2; % Or any number you want
for recIdx = 1:n_recording
fprintf('Recording %d / %d\n', recIdx, n_recording);
%% Acquire Scope Signal
Scpe_sig_raw = Scp.read("channel",[0,0,1,0]);
Scpe_sig_raw = Scpe_sig_raw{[0,0,1,0]==1};
% Precompensation Routine (optional)
if precomp_mode == 1
precomp_est.estimate(Scpe_sig_raw, "save", true, "savePath", precomp_path, "fileName", precomp_fn);
precomp_est.plot();
return; % End routine if precomp mode is active
end
% Plot spectrum and time domain (optional)
% Scpe_sig_raw.spectrum("displayname", 'Rx Spectrum', 'fignum', 10, 'normalizeTo0dB', 0);
Scpe_sig_raw.plot("clear", 1, "displayname", 'Rx Signal', 'fignum', 11);
%% Save Routine
currentTime = datetime('now', 'Format', 'yyyyMMdd_HHmmss');
timeStr = char(currentTime);
filename = sprintf('%s_PAM_%d_R_%d_rec%02d', timeStr, conf.pam_level, round(conf.symbolrate.*1e-9), recIdx); % Added recIdx
rx_raw_path = [filesep, current_folder, filesep, filename, '_rx_signal_raw'];
save([savePath, rx_raw_path], "Scpe_sig_raw");
% Table 1: Append to Runs
newRun = db.tables.Runs;
newRun.run_id = NaN;
newRun.date_of_run = datetime(currentTime, 'InputFormat', 'yyyyMMdd_HHmmss');
newRun.tx_bits_path = tx_bits_path;
newRun.tx_symbols_path = tx_symbols_path;
newRun.rx_sync_path = [];
newRun.rx_raw_path = rx_raw_path;
newRun.filename = filename;
newRun.tx_signal_path = tx_signal_path;
run_id = db.appendToTable('Runs', newRun);
% Check if loop_id is already created
if isempty(loop_id)
newLoop = db.tables.LoopControl;
newLoop.loop_id = NaN;
newLoop.date_of_loop = datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss');
newLoop.description = 'Automated parameter sweep';
loop_id = db.appendToTable('LoopControl', newLoop);
% Table 2: Append to Configurations
conf.configuration_id = NaN;
conf.run_id = run_id;
db.appendToTable('Configurations', conf);
fprintf('LoopControl entry created: loop_id = %d\n', loop_id);
end
% Table 3: Append to Measurements
meas = db.tables.Measurements;
meas.measurement_id = NaN; % Auto-increment, leave empty
meas.run_id = run_id;
meas.power_laser = laser.cur_power;
meas.power_rop = [];
meas.power_pd_in = voa.power_state(2);
meas.power_mpi_interference = voa.power_state(4);
meas.power_mpi_signal = voa.power_state(3);
meas.voa_class = voa;
meas.pdfa_class = pdfa;
meas.laser_class = laser;
assert(isequal(fieldnames(meas), fieldnames(db.tables.Measurements)), 'Fieldnames of "meas" do not match the reference structure!');
db.appendToTable('Measurements', meas);
%% Append to Runs Table
newRun = db.tables.Runs;
newRun.run_id = NaN;
newRun.loop_id = loop_id;
newRun.date_of_run = datetime(currentTime, 'InputFormat', 'yyyyMMdd_HHmmss');
newRun.tx_bits_path = tx_bits_path;
newRun.tx_symbols_path = tx_symbols_path;
newRun.rx_sync_path = []; % Leave empty for now
newRun.rx_raw_path = rx_raw_path;
newRun.filename = filename;
newRun.tx_signal_path = tx_signal_path;
%% %%%%% DSP Routine %%%%%%%%%%%%%%%%%%%%%%%%%
run_id = db.appendToTable('Runs', newRun);
[out, ~] = submit_dsp(run_id, basePath, database_name, savePath,"parallel",parallel_dsp,'max_occurences',max_occurences);
%% Append to Configurations Table
conf.configuration_id = NaN;
conf.run_id = run_id;
db.appendToTable('Configurations', conf);
%% Append to Measurements Table
meas = db.tables.Measurements;
meas.measurement_id = NaN;
meas.run_id = run_id;
meas.power_laser = laser.cur_power;
meas.power_rop = [];
meas.power_pd_in = voa.power_state(2);
meas.power_mpi_interference = voa.power_state(4);
meas.power_mpi_signal = voa.power_state(3);
meas.voa_class = voa;
meas.pdfa_class = pdfa;
meas.laser_class = laser;
% Ensure consistency
assert(isequal(fieldnames(meas), fieldnames(db.tables.Measurements)), 'Fieldnames of "meas" do not match the reference structure!');
db.appendToTable('Measurements', meas);
%% Submit DSP Routine
% [out, ~] = submit_dsp(run_id, basePath, database_name, savePath, ...
% "parallel", parallel_dsp, "max_occurences", max_occurences);
end