diff --git a/Classes/00_signals/Frame 1.png b/Classes/00_signals/Frame 1.png deleted file mode 100644 index b1797d7..0000000 Binary files a/Classes/00_signals/Frame 1.png and /dev/null differ diff --git a/Classes/00_signals/Signal.m b/Classes/00_signals/Signal.m index 676d04a..b601d40 100644 --- a/Classes/00_signals/Signal.m +++ b/Classes/00_signals/Signal.m @@ -349,13 +349,13 @@ classdef Signal % spectrum_plot(obj.signal,options.fsamp,options.figurename,options.displayname); - N = 2^(nextpow2(length(obj.signal))-2); + N = 2^(nextpow2(length(obj.signal))-9); if options.normalizeToNyquist==0 - [p_lin,w] = pwelch(obj.signal,hanning(N),N/2,N,obj.fs,"centered","power","mean"); + [p_lin,w] = pwelch(obj.signal,hanning(N),N/2,N,obj.fs,"centered","psd","mean"); w=w.*1e-9; else - [p_lin,w] = pwelch(obj.signal,hanning(N),N/2,N,"centered","power","mean"); + [p_lin,w] = pwelch(obj.signal,hanning(N),N/2,N,"centered","psd","mean"); % p_lin = smooth(p_lin,0.05,'rloess'); end @@ -365,7 +365,7 @@ classdef Signal p_dbm = 10*log10(p_lin); %dB to dBm in case of "power" ylab = "normalized to 0 dB"; else - p_dbm = 10*log10(p_lin)+30; %dB to dBm in case of "power" + p_dbm = 10*log10(p_lin); %dB to dBm in case of "power" ylab = "Power (dBm)"; end @@ -401,6 +401,125 @@ classdef Signal end + function move_it_spectrum(obj,options) + arguments + obj + options.fignum + options.displayname = ""; + options.color = []; + options.normalizeToNyquist = 0; + options.normalizeTo0dB = 0; + end + + data_in = obj.signal; + + if size(data_in,1) > size(data_in,2) + data_in = data_in'; + end + + for pol = 1:size(data_in,1) + + %compute FFT of input + Data_in = fft( data_in(pol,:) ); + + %psd = Data_in.*conj(Data_in); + psd = Data_in; + + %Use only magnitude of FFT (which was complex) + psd = abs(psd); + + %Shift the spectrum to yield + psd = fftshift(psd); + + %divide by N + psd = psd/length(data_in(pol,:)); + + psd_plot = 20*log10(psd); + + % psd_plot = psd_plot - max(psd_plot); + + + %smoothing + % psd_smoothed = smooth(psd,1000); + % + % psd_smoothed = 10*log10(psd_smoothed); + + % psd_smoothed = psd_smoothed - max(psd_smoothed); + + carrier_power_time_dbm = 20*log10( mean(abs(data_in)) .^2 )+30; % dB -> +30 -> dBm + carrier_power_freq_dbm = max(psd_plot); + + + % psd_plot = psd_plot - max(psd_plot); + + %% cspr + c = mean(data_in).^2; + s = mean(data_in.^2); + cspr = 10*log10(c / s); + + testParseval = 1; + + if testParseval == 1 + + E_FreqDomain =1/length(psd) * sum((psd.*length(psd)).^2); + + %test parseval + E_TimeDomain = sum( (data_in(pol,:).^2) ); + + if isequal(round(E_FreqDomain,1),round(E_TimeDomain,1)) + disp('Parseval is right!'); + else + % disp('Something is wrong here?!'); + end + end + + figure(options.fignum); % If figure does not exist, create new figure + + if 1 + %Frequency Axis + freq_vec = linspace(-obj.fs/2,obj.fs/2,length(psd)); + freq_vec = reshape(freq_vec,size(psd_plot)); + + + if nargin == 4 + p = plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5,'DisplayName',options.displayname); + % plot(freq_vec*1e-9,psd_smoothed','Linewidth',1,'Color',[0 0 0],'DisplayName',[char(varargin{2}),' smoothed']); + + else + p = plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5); + % plot(freq_vec*1e-9,psd_smoothed','Linewidth',1,'Color',[1 1 1],'LineStyle',':'); + + end + + %xlim([freq_vec(1)/1e9-2 freq_vec(end)/1e9+2]) + xlabel('frequency [GHz]') + else + %Wavelength Axis + freq_vec = physconst('LightSpeed')*linspace(-obj.fs/2,obj.fs/2,length(psd))./((physconst('LightSpeed')/1310e-9)^2)*1e9; + freq_vec = freq_vec+1310; + if nargin == 4 + plot(freq_vec',psd_plot,'Linewidth',0.5,'DisplayName',options.displayname) + else + plot(freq_vec,psd_plot','Linewidth',0.5); + end + + %xlim([freq_vec(1)/1e9-2 freq_vec(end)/1e9+2]) + xlabel('wavelength [nm]') + end + hold on + + + end + + % xlim([-150 150]) + % ylim([-100,0]); + ylabel('magnitude [dBm]') + legend + grid minor; + + + end + %% Power of signal function pow = power(obj,options) @@ -544,7 +663,7 @@ classdef Signal %Cut occurences of ref signal from signal (only positive shifts) S = {}; - for c = shifts(shifts>0) + for c = shifts(shifts>=0) sig = obj.delay(-c,'mode','samples'); sig.signal = sig.signal(1:length(b)); S{end+1,1} = sig; @@ -557,7 +676,7 @@ classdef Signal end %return/keep the sinal with the highest correlation (only within positive shifts) - [~,idx]=max(pks(shifts>0)); + [~,idx]=max(pks(shifts>=0)); obj.signal = S{idx}.signal; %put signal with highest corr. to first index in S array swap = S{1}; diff --git a/Classes/01_transmit/AWG.m b/Classes/01_transmit/AWG.m index 4a60a1d..6a6e894 100644 --- a/Classes/01_transmit/AWG.m +++ b/Classes/01_transmit/AWG.m @@ -8,6 +8,7 @@ classdef AWG < handle upsampling_method repetitions %repeat the signal to generate a longer sequence? fdac %needed + precomp_sinc_rolloff = 1; normalize2dac %want to normalize at first? either 0 or 1 bit_resolution %bit res. of quantizer (e.g. 5 bit) dac_min @@ -33,7 +34,8 @@ classdef AWG < handle arguments options.kover = 16; - options.upsampling_method upsampling_mode + options.upsampling_method upsampling_mode = upsampling_mode.samplehold; + options.precomp_sinc_rolloff = 1; options.repetitions = 1; options.normalize2dac = 1; options.fdac = 92e9; @@ -43,7 +45,7 @@ classdef AWG < handle options.skew_active = 0; options.awg_skew = 0; options.lpf_active = 0; - options.lpf_type = 0; + options.lpf_type = filtertypes.butterworth; options.f_cutoff = 32e9; options.H_lpf Filter @@ -95,7 +97,7 @@ classdef AWG < handle signalclass_in = obj.H_lpf.process(signalclass_in); else %4.B) just use a standard filter - lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fsamp",obj.kover*obj.fdac,"filterType",obj.lpf_type); + lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fs",obj.kover*obj.fdac,"filterType",obj.lpf_type); signalclass_in = lpf.process(signalclass_in); end end @@ -133,7 +135,7 @@ classdef AWG < handle obj.signal_length = length(data_in); %%%%%%%%% PRECOMP SINC ROLLOFF %%%%%%%%% - if 1 + if obj.precomp_sinc_rolloff % X: design FIR filter for sinc precomp % https://www.dsprelated.com/showarticle/1191.php ntaps = 13; diff --git a/Classes/01_transmit/PAMsource.m b/Classes/01_transmit/PAMsource.m index 4e96911..4a410a0 100644 --- a/Classes/01_transmit/PAMsource.m +++ b/Classes/01_transmit/PAMsource.m @@ -151,6 +151,12 @@ classdef PAMsource sym_max = max(symbols.signal); end + % symbols.move_it_spectrum("fignum",222,"displayname","Symbols only"); + + + % symbols.spectrum("fignum",222,"displayname","Symbols only","normalizeTo0dB",1); + + %%%%% Pulse-forming %%%%%% if obj.applypulseform digi_sig = obj.pulseformer.process(symbols); diff --git a/Classes/04_DSP/Coding/Duobinary.m b/Classes/04_DSP/Coding/Duobinary.m index 5801163..00f8e0c 100644 --- a/Classes/04_DSP/Coding/Duobinary.m +++ b/Classes/04_DSP/Coding/Duobinary.m @@ -1,10 +1,9 @@ classdef Duobinary %Duobinary Coding - % should work - + % should work + properties(Access=public) - end methods (Access=public) @@ -12,6 +11,7 @@ classdef Duobinary function obj = Duobinary() %NAME Construct an instance of this class + end function signal = precode(~,signal) @@ -52,7 +52,7 @@ classdef Duobinary % end for k = 2:numel(data) - bk(k) =mod(data(k)-bk(k-1),M); + bk(k) = mod(data(k)-bk(k-1),M); end %make bipolar @@ -80,6 +80,11 @@ classdef Duobinary function signal = encode(~,signal) + arguments + ~ + signal + end + if isa(signal,'Signal') data = signal.signal; else @@ -138,6 +143,8 @@ classdef Duobinary data = data ./ sqrt(5.8); elseif M == 8 data = data ./ sqrt(10.5); % 15-level constellation weighted with probability after DB code i.e. + else + errormsg("Error in: Duobinary encode > scale unipolar to bipolar > The data is not PAM4, PAM6 or PAM 8? ") end if isa(signal,'Signal') @@ -169,13 +176,9 @@ classdef Duobinary if I == 7 data = data .* sqrt(2.5); elseif I == 11 - %todo data = data .* sqrt(5.8); - warning('Check db decode implementation, mapping and scaling is correct!') elseif I == 15 data = data .* sqrt(10.5); - elseif I == 16 - warning('Check db decode implementation, mapping and scaling is correct!') end data = round(data); @@ -196,6 +199,8 @@ classdef Duobinary data = data ./ sqrt(10); elseif M == 8 data = data ./ sqrt(21); + else + errormsg("Error in: Duobinary decode > scale unipolar to bipolar > The data is not PAM4, PAM6 or PAM 8? ") end signalclass.signal = data; diff --git a/Classes/04_DSP/Equalizer/Postfilter.m b/Classes/04_DSP/Equalizer/Postfilter.m index 9f72a58..8ec5280 100644 --- a/Classes/04_DSP/Equalizer/Postfilter.m +++ b/Classes/04_DSP/Equalizer/Postfilter.m @@ -45,14 +45,14 @@ classdef Postfilter < handle function showFilter(obj,noiseclass_in) - noiseclass_in.spectrum('displayname','Noise PSD shifted to 0dBm','fignum',123,'normalizeTo0dB',1); + noiseclass_in.spectrum('displayname','Noise PSD shifted to 0dBm','fignum',121,'normalizeTo0dB',1); [h,w] = freqz(1,obj.burg_coeff,length(noiseclass_in),"whole",noiseclass_in.fs); h = h/max(abs(h)); hold on w_ = (w - noiseclass_in.fs/2); - plot(w_.*1e-9,20*log10(fftshift(h)),'DisplayName',['Burg Coeffs: ', num2str(obj.burg_coeff), ' ']); - + plot(w_.*1e-9,20*log10(fftshift(abs(h))),'DisplayName',['Burg Coeffs: ', num2str(obj.burg_coeff), ' ']); + ylim([-30,2]); end end diff --git a/Classes/DataBaseHandler/DBHandler.m b/Classes/DataBaseHandler/DBHandler.m index 2baaaef..6db91a3 100644 --- a/Classes/DataBaseHandler/DBHandler.m +++ b/Classes/DataBaseHandler/DBHandler.m @@ -159,7 +159,7 @@ classdef DBHandler < handle duplictae_sync = obj.fetch("SELECT COALESCE(Runs.rx_sync_path,'NaN') AS rx_sync_path, COUNT(*) AS occurrences FROM Runs GROUP BY rx_sync_path HAVING COUNT(*) > 1"); if size(duplictae_raw,2) > 1 - for i = 1:size(duplictae_raw,2)-1 + for i = 1:size(duplictae_raw,1) fprintf('Raw Rx Paths: Found %d duplictaes of %s \n',duplictae_raw.occurrences(i),duplictae_raw.rx_raw_path(i)); end end @@ -349,6 +349,11 @@ classdef DBHandler < handle + function executeSQL(obj, query) + % This method executes an SQL statement using MATLAB's execute function. + execute(obj.conn, query); + end + function answer = fetch(obj,query) answer = fetch(obj.conn,query); diff --git a/Classes/Warehouse_class/classes/DataStorage.m b/Classes/Warehouse_class/classes/DataStorage.m index af00a6a..434bb97 100644 --- a/Classes/Warehouse_class/classes/DataStorage.m +++ b/Classes/Warehouse_class/classes/DataStorage.m @@ -114,6 +114,12 @@ classdef DataStorage < handle end + function addValueToStorageByLinIdx(obj, valueToStore ,storageVarName, lin_idx) + + obj.sto.(storageVarName){lin_idx} = valueToStore; + + end + % Access Value(s) function value = getStoValue(obj,storageVarName, varargin) @@ -270,7 +276,7 @@ classdef DataStorage < handle - function phys_indices = getPhysIndicesByLinIndex(obj, lin_idx) + function [phys_indices,param_name] = getPhysIndicesByLinIndex(obj, lin_idx) % Converts a linear index into the corresponding physical parameter values % Inputs: % - lin_idx: The linear index within the storage array @@ -285,8 +291,8 @@ classdef DataStorage < handle % Map subscripts to physical values for each parameter for i = 1:numel(obj.fn) - param_name = obj.fn(i); - phys_indices{i} = obj.parameter.(param_name).getPhysForIndex(subscripts{i}); + param_name{i} = obj.fn(i); + phys_indices{i} = obj.parameter.(param_name{i}).getPhysForIndex(subscripts{i}); end end diff --git a/Classes/Warehouse_class/classes/DataStorage2.m b/Classes/Warehouse_class/classes/DataStorage2.m deleted file mode 100644 index 018f51c..0000000 --- a/Classes/Warehouse_class/classes/DataStorage2.m +++ /dev/null @@ -1,114 +0,0 @@ -classdef DataStorage2 < handle - % DATASTORAGE: Stores data with physical parameter mappings - - properties - inputParams = struct; - parameter = struct; - fn = []; - dim = []; - sto = struct; - end - - methods - function obj = DataStorage2(inputParams) - % Constructor to initialize the DataStorage object - if nargin > 0 - obj.inputParams = inputParams; - obj.fn = string(fieldnames(inputParams)); - obj = obj.buildParameter(); - obj.dim = obj.getDimension(); - obj.sto = struct; - else - error('Input parameters are required.'); - end - - end - - function showInfo(obj) - % Displays information about the storage and its dimensions - disp("Data Structure with fields:"); - fprintf('%-12s | %-8s | %-12s\n', 'Name', 'Dimension', 'Physical Values'); - disp('-------------------------------------------------------'); - for i = 1:numel(obj.fn) - fprintf('%-12s | %-8d | %-12s\n', ... - char(obj.fn(i)), obj.dim(i), ... - strjoin(string(obj.parameter.(obj.fn(i)).values), ', ')); - end - disp('-------------------------------------------------------'); - end - - function dim = getDimension(obj) - % Get the dimensions based on the length of parameters - dim = zeros(1, numel(obj.fn)); - for p = 1:numel(obj.fn) - dim(p) = obj.parameter.(obj.fn(p)).length; - end - end - - function obj = buildParameter(obj) - % Build the Parameter objects for each input parameter - for p = 1:numel(obj.fn) - name = obj.fn(p); - values = obj.inputParams.(name); - obj.parameter.(name) = Parameter2(name, values); - end - end - - function addStorage(obj, varName) - % Create an empty storage for a specific variable name - obj.sto.(string(varName)) = cell(obj.dim); - end - - function addValueToStorage(obj, valueToStore, storageVarName, varargin) - % Add a value to the storage at the specified indices - if nargin - 3 == numel(obj.fn) - lin_idx = obj.getIndicesByPhys(varargin); - obj.sto.(storageVarName){lin_idx} = valueToStore; - else - error('Please provide all indices for the storage.'); - end - end - - function value = getStoValue(obj, storageVarName, varargin) - % Retrieve a value from storage based on physical parameters - if nargin - 2 == numel(obj.fn) - lin_idx = obj.getIndicesByPhys(varargin); - value = cell(1, numel(lin_idx)); - for i = 1:numel(lin_idx) - value{i} = obj.sto.(storageVarName){lin_idx(i)}; - end - value = value(~cellfun('isempty', value)); % Remove empty entries - else - error('Please provide all physical parameters.'); - end - end - - function lin_idx = getIndicesByPhys(obj, varargin) - % Unpack nested cell array if needed - if numel(varargin) == 1 && iscell(varargin{1}) - varargin = varargin{1}; % Unpack if single cell array is passed - end - - indices = cell(1, numel(obj.fn)); - - % Loop through each parameter (e.g., L, D) - for p = 1:numel(obj.fn) - % Unwrap if it's a cell - if iscell(varargin{p}) - physVal = varargin{p}{1}; % Extract scalar from cell - else - physVal = varargin{p}; % It's already a scalar - end - - paramName = obj.fn(p); % Get the parameter name (e.g., 'L' or 'D') - - % Call getIndexByPhys on the corresponding Parameter2 object - indices{p} = obj.parameter.(paramName).getIndexByPhys(physVal); - end - - % Convert subscript indices to a linear index - lin_idx = sub2ind(obj.dim, indices{:}); - end - - end -end diff --git a/Classes/Warehouse_class/classes/Parameter2.m b/Classes/Warehouse_class/classes/Parameter2.m deleted file mode 100644 index 84852ff..0000000 --- a/Classes/Warehouse_class/classes/Parameter2.m +++ /dev/null @@ -1,51 +0,0 @@ -classdef Parameter2 < handle - % PARAMETER2: Represents a physical parameter with mappings between values and indices - - properties - name - values - length - physToIndexMap % Rename this from 'getPhysForIndex' - indexToPhysMap % Rename this from 'getIndexForPhys' - end - - methods - function obj = Parameter2(name, values) - % Constructor to initialize the Parameter2 object - obj.name = name; - obj.values = values; - obj.length = numel(values); - - % Initialize the mappings - obj.physToIndexMap = containers.Map('KeyType', 'double', 'ValueType', 'any'); - obj.indexToPhysMap = containers.Map('KeyType', 'double', 'ValueType', 'any'); - obj = obj.buildMappings(); - end - - function obj = buildMappings(obj) - % Build mappings between physical values and indices - for idx = 1:obj.length - obj.indexToPhysMap(idx) = obj.values(idx); - obj.physToIndexMap(obj.values(idx)) = idx; - end - end - - function physVal = getPhysForIndex(obj, idx) - % Return the physical value corresponding to the index - if isKey(obj.indexToPhysMap, idx) - physVal = obj.indexToPhysMap(idx); - else - error('Index out of range for parameter %s', obj.name); - end - end - - function idx = getIndexByPhys(obj, physVal) - % Return the index corresponding to the physical value - if isKey(obj.physToIndexMap, physVal) - idx = obj.physToIndexMap(physVal); - else - error('Physical value %g not found in parameter %s', physVal, obj.name); - end - end - end -end diff --git a/Classes/Warehouse_class/classes/minimalExample_gen2.m b/Classes/Warehouse_class/classes/minimalExample_gen2.m deleted file mode 100644 index c348197..0000000 --- a/Classes/Warehouse_class/classes/minimalExample_gen2.m +++ /dev/null @@ -1,45 +0,0 @@ -% Define input parameters for the DataStorage2 -inputParams.L = [1, 2, 10, 80]; % Length in kilometers -inputParams.D = [16, 17, 18]; % Diameter in millimeters - -% Create a DataStorage2 instance with the input parameters -dataStorage = DataStorage2(inputParams); % Using DataStorage2 class - -% Display the current information about the data storage structure -dataStorage.showInfo(); - -% Add a storage variable named 'testStorage' -dataStorage.addStorage('testStorage'); - -% Add a value (e.g., 100) to the storage at specific physical parameter values -% For example, we store the value 100 at L = 10 km and D = 17 mm -dataStorage.addValueToStorage(100, 'testStorage', 10, 16); -dataStorage.addValueToStorage(100, 'testStorage', 10, 17); -dataStorage.addValueToStorage(100, 'testStorage', 10, 18); - -% Retrieve the value from the storage at the same physical parameter values -storedValue = dataStorage.getStoValue('testStorage', 10, 16:18); -disp('Retrieved value from storage:'); -disp(storedValue); - -% Retrieve another value at a non-existent location (L = 2 km, D = 8 mm) -% This will show how the function handles empty storage entries -nonExistentValue = dataStorage.getStoValue('testStorage', 2, 8); -disp('Retrieved value from empty location:'); -disp(nonExistentValue); - -% Use the internal mappings to check how physical values map to indices -% Get the linear index for physical values L = 10 km and D = 17 mm -lin_idx = dataStorage.getIndicesByPhys(10, 17); -disp('Linear index for L=10 km and D=17 mm:'); -disp(lin_idx); - -% Check the reverse mapping: physical value for index 2 of parameter L -physValForIndex = dataStorage.parameter.L.getPhysForIndex(2); -disp('Physical value for index 2 of parameter L:'); -disp(physValForIndex); - -% Check the mapping: index for physical value D = 21 mm -indexForPhys = dataStorage.parameter.D.getIndexByPhys(21); -disp('Index for physical value D=21 mm:'); -disp(indexForPhys); diff --git a/Classes/matlab.mat b/Classes/matlab.mat deleted file mode 100644 index e33da65..0000000 Binary files a/Classes/matlab.mat and /dev/null differ diff --git a/Datatypes/db_mode.m b/Datatypes/db_mode.m index 9b22523..728f38c 100644 --- a/Datatypes/db_mode.m +++ b/Datatypes/db_mode.m @@ -4,6 +4,7 @@ classdef db_mode < int32 no_db (0) db_precoded (1) db_encoded (2) + db_emulate (3) end end \ No newline at end of file diff --git a/Functions/EQ_structures/vnle.m b/Functions/EQ_structures/vnle.m index 6b32987..c4e266c 100644 --- a/Functions/EQ_structures/vnle.m +++ b/Functions/EQ_structures/vnle.m @@ -1,4 +1,4 @@ -function [eq_signal,eq_noise,ber,numErrors] = vnle(EQ,M,rx_signal,tx_symbols,tx_bits) +function [eq_signal,eq_noise,ber,numErrors] = vnle(EQ,M,rx_signal,tx_symbols,tx_bits,emulate_precode) %VNLE Apply an equalization algorithm to the received signal and calculate BER % This function takes an equalizer object, a received signal, and the % transmitted symbols to apply equalization, map the received signal back to bits, @@ -16,6 +16,17 @@ function [eq_signal,eq_noise,ber,numErrors] = vnle(EQ,M,rx_signal,tx_symbols,tx_ %FFE or VNLE [eq_signal,eq_noise] = EQ.process(rx_signal,tx_symbols); + + eq_signal = PAMmapper(M,0).quantize(eq_signal); + + if emulate_precode + eq_signal = Duobinary().encode(eq_signal); + eq_signal = Duobinary().decode(eq_signal); + + tx_symbols= Duobinary().encode(tx_symbols); + tx_symbols = Duobinary().decode(tx_symbols); + tx_bits = PAMmapper(M,0).demap(tx_symbols); + end % M = numel(unique(tx_symbols.signal)); rx_bits = PAMmapper(M,0).demap(eq_signal); diff --git a/Functions/EQ_structures/vnle_postfilter_mlse.m b/Functions/EQ_structures/vnle_postfilter_mlse.m index a022b19..83a8b83 100644 --- a/Functions/EQ_structures/vnle_postfilter_mlse.m +++ b/Functions/EQ_structures/vnle_postfilter_mlse.m @@ -3,12 +3,15 @@ function [eq_signal,eq_noise,ber,numErrors] = vnle_postfilter_mlse(eq_,pf_,mlse_ %FFE or VNLE [eq_signal,eq_noise] = eq_.process(rx_signal,tx_symbols); + % eq_noise.signal = eq_noise.signal - movmean(eq_noise.signal,[5000,0]); + eq_signal = pf_.process(eq_signal,eq_noise); %M = numel(unique(tx_symbols.signal)); mlse_.DIR = pf_.burg_coeff; mlse_.trellis_states = PAMmapper(M,0).levels; mlse_.M = M; + eq_signal = mlse_.process(eq_signal); rx_bits = PAMmapper(M,0).demap(eq_signal); diff --git a/Functions/beautifyBERplot.m b/Functions/beautifyBERplot.m new file mode 100644 index 0000000..a50f626 --- /dev/null +++ b/Functions/beautifyBERplot.m @@ -0,0 +1,57 @@ +function beautifyBERplot() + % BEAUTIFYBERPLOT Enhances a BER plot for publication-quality figures. + % + % This function automatically adjusts the aesthetics of an existing plot. + % It sets limits based on the data already plotted and modifies the + % appearance for publication-ready figures. + + % Set line properties for all current plot lines + lines = findall(gca, 'Type', 'Line'); + markers = {'o', 's', 'd', '^', 'v', '>', '<', 'p', 'h'}; % Define marker styles + num_markers = length(markers); + + for i = 1:length(lines) + lines(i).LineWidth = 1.5; % Set a thicker line width + lines(i).LineStyle = '-'; % Solid lines for simplicity + lines(i).Marker = markers{mod(i-1, num_markers) + 1}; % Assign markers cyclically + lines(i).MarkerSize = 6; % Set marker size + lines(i).MarkerFaceColor = 'auto'; % Use line color for marker face + end + + % Change all text interpreters to LaTeX + set(findall(gca, '-property', 'Interpreter'), 'Interpreter', 'latex'); + + % Set figure background to white + set(gcf, 'Color', 'w'); + + % Set axis labels with LaTeX + xlabel('Bit Rate in Gbps', 'Interpreter', 'latex'); + ylabel('Bit Error Rate', 'Interpreter', 'latex'); + + % Determine x and y limits from the data in the plot + x_data = []; + y_data = []; + for i = 1:length(lines) + x_data = [x_data; lines(i).XData(:)]; %#ok % Append x data + y_data = [y_data; lines(i).YData(:)]; %#ok % Append y data + end + x_min = min(x_data); + x_max = max(x_data); + y_min = 1e-4; % Ensure no negative or zero values for log scale + y_max = 0.5; + + % Adjust axis ranges + xlim([x_min, x_max]); + ylim([y_min, y_max]); + + % Set logarithmic scale for y-axis + set(gca, 'YScale', 'log'); + + % Customize grid and box appearance + set(gca, 'Box', 'on', 'LineWidth', 1.2); % Add a thicker border + grid on; + grid minor; + + % Adjust font size and style for better readability + set(gca, 'FontSize', 12, 'FontName', 'Times New Roman'); +end diff --git a/Functions/channel_structures/awgn_channel.m b/Functions/channel_structures/awgn_channel.m new file mode 100644 index 0000000..6cf5580 --- /dev/null +++ b/Functions/channel_structures/awgn_channel.m @@ -0,0 +1,5 @@ +function signal_out = awgn_channel(signal_in) + + signal_out = signal_in; + +end \ No newline at end of file diff --git a/Functions/copyStylingFrom.m b/Functions/copyStylingFrom.m new file mode 100644 index 0000000..aaf110f --- /dev/null +++ b/Functions/copyStylingFrom.m @@ -0,0 +1,76 @@ +function copyStylingFrom(figNumSource, figNumTgt) + % Get handles to the source and target figures + sourceFig = figure(figNumSource); + targetFig = figure(figNumTgt); + + % Get axes of source and target figures + sourceAxes = findall(sourceFig, 'type', 'axes'); + targetAxes = findall(targetFig, 'type', 'axes'); + + % Ensure the number of axes match + if length(sourceAxes) ~= length(targetAxes) + error('Number of axes in source and target figures must be the same.'); + end + + % Loop through each pair of axes and copy styling properties + for i = 1:length(sourceAxes) + copyAxesProperties(sourceAxes(i), targetAxes(i)); + end + + % Apply general figure properties if desired + targetFig.Color = sourceFig.Color; % Background color +end + +function copyAxesProperties(sourceAx, targetAx) + % List of properties to copy from source to target axes + propsToCopy = {'XColor', 'YColor', 'ZColor', 'FontSize', 'FontName', ... + 'GridColor', 'GridLineStyle', 'MinorGridColor', 'Box', ... + 'XGrid', 'YGrid', 'ZGrid', 'XMinorGrid', 'YMinorGrid', 'ZMinorGrid', ... + 'LineWidth', 'TitleFontSizeMultiplier', 'LabelFontSizeMultiplier'}; + + % Copy properties from source to target + for i = 1:length(propsToCopy) + try + targetAx.(propsToCopy{i}) = sourceAx.(propsToCopy{i}); + catch + % Skip property if it doesn't exist or can't be copied + end + end + + % Copy axis labels and titles + targetAx.Title.String = sourceAx.Title.String; + targetAx.XLabel.String = sourceAx.XLabel.String; + targetAx.YLabel.String = sourceAx.YLabel.String; + targetAx.ZLabel.String = sourceAx.ZLabel.String; + + % Copy children elements like lines, patches, etc. + sourceChildren = allchild(sourceAx); + targetChildren = allchild(targetAx); + + % Ensure the number of children elements match + if length(sourceChildren) ~= length(targetChildren) + warning('Number of elements in source and target axes differ. Styling may not be applied completely.'); + end + + % Copy properties of children (like lines, patches, etc.), except colors and legends + for i = 1:min(length(sourceChildren), length(targetChildren)) + copyObjectProperties(sourceChildren(i), targetChildren(i)); + end +end + +function copyObjectProperties(sourceObj, targetObj) + % List of common properties to copy for plot elements (lines, patches, etc.) + propsToCopy = {'LineStyle', 'LineWidth', 'Marker', 'MarkerSize', ... + 'MarkerEdgeColor', 'MarkerFaceColor', 'DisplayName'}; + + % Copy properties from source to target, excluding colors + for i = 1:length(propsToCopy) + try + if ~contains(propsToCopy{i}, 'Color') % Skip color properties + targetObj.(propsToCopy{i}) = sourceObj.(propsToCopy{i}); + end + catch + % Skip property if it doesn't exist or can't be copied + end + end +end diff --git a/projects/HighSpeedExperiment_2024/removeDotsFromFileNames.m b/Functions/removeDotsFromFileNames.m similarity index 100% rename from projects/HighSpeedExperiment_2024/removeDotsFromFileNames.m rename to Functions/removeDotsFromFileNames.m diff --git a/db_eq_mpi.tex b/db_eq_mpi.tex deleted file mode 100644 index 12994d7..0000000 --- a/db_eq_mpi.tex +++ /dev/null @@ -1,290 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.89020,0.10196,0.10980}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=-3.14159265358979, -xmax=3.14159265358979, -xlabel style={font=\color{white!15!black}}, -xlabel={Normalized Frequency}, -ymin=-46, -ymax=3, -ytick={-200, -190, -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, 0, 10}, -ylabel style={font=\color{white!15!black}}, -ylabel={normalized to 0 dB}, -axis background/.style={fill=white}, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -xminorgrids, -ymajorgrids, -yminorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, line width=1.0pt] - table[row sep=crcr]{% --3.11704896098362 -34.152640124107\\ --3.09250526837745 -37.30368249791\\ --3.06796157577129 -36.4084155134507\\ --3.04341788316511 -32.8472897555048\\ --3.01887419055894 -29.7603420288457\\ --2.99433049795277 -27.3878352702008\\ --2.9697868053466 -25.5045919439843\\ --2.94524311274043 -23.8596773095355\\ --2.92069942013426 -22.4231778333755\\ --2.89615572752809 -21.0738854605452\\ --2.87161203492192 -19.8241748642718\\ --2.84706834231575 -18.7656037744813\\ --2.82252464970958 -17.9427012863468\\ --2.79798095710341 -17.3300455020831\\ --2.77343726449724 -16.8570972623564\\ --2.74889357189107 -16.4303665810903\\ --2.7243498792849 -15.9603331293506\\ --2.67526249407256 -14.9152364147404\\ --2.62617510886022 -13.7282789909322\\ --2.60163141625405 -13.2711055669692\\ --2.57708772364788 -13.0159869302563\\ --2.55254403104171 -12.8627077954076\\ --2.52800033843554 -12.6991459702061\\ --2.50345664582937 -12.4271267312005\\ --2.47891295322319 -11.8866214027661\\ --2.45436926061703 -11.0536074564346\\ --2.42982556801086 -10.1083695425263\\ --2.40528187540468 -9.31388042827889\\ --2.38073818279852 -8.778725491267\\ --2.35619449019234 -8.39313608791176\\ --2.33165079758618 -8.14092384893069\\ --2.30710710498001 -8.06093370603605\\ --2.28256341237383 -8.14161353993601\\ --2.25801971976767 -8.27290604595128\\ --2.23347602716149 -8.36591478049129\\ --2.20893233455532 -8.43416110047679\\ --2.18438864194916 -8.4380075354912\\ --2.15984494934298 -8.30596285747854\\ --2.13530125673681 -8.1165797444491\\ --2.11075756413064 -7.98175190194559\\ --2.08621387152447 -7.8619798953406\\ --2.06167017891831 -7.69653976428778\\ --2.03712648631213 -7.4271708098562\\ --2.01258279370596 -7.04574805161646\\ --1.98803910109979 -6.57390723520547\\ --1.96349540849362 -6.06771072445017\\ --1.93895171588745 -5.63493976637049\\ --1.91440802328128 -5.34213348629677\\ --1.88986433067511 -5.15834304528927\\ --1.86532063806894 -5.06241865677818\\ --1.84077694546277 -5.00995310954403\\ --1.8162332528566 -4.94933187405054\\ --1.79168956025043 -4.89778434539084\\ --1.76714586764426 -4.91128987148945\\ --1.74260217503809 -4.93802078574208\\ --1.71805848243192 -4.97303502588234\\ --1.69351478982575 -4.97451045806658\\ --1.66897109721958 -4.95636002488353\\ --1.64442740461341 -4.90272361408173\\ --1.61988371200724 -4.81348152997761\\ --1.59534001940106 -4.74564957733824\\ --1.5707963267949 -4.70301446670535\\ --1.54625263418873 -4.63831980162999\\ --1.52170894158255 -4.5187929199835\\ --1.49716524897639 -4.34815184803496\\ --1.47262155637021 -4.1192135361535\\ --1.42353417115788 -3.54761072032757\\ --1.3989904785517 -3.29683622342827\\ --1.37444678594554 -3.13389750127856\\ --1.34990309333936 -3.00703329422139\\ --1.32535940073319 -2.93820099699774\\ --1.30081570812703 -2.93351704789859\\ --1.27627201552085 -2.93615105708502\\ --1.25172832291468 -2.94778942364624\\ --1.22718463030851 -2.97707904052072\\ --1.17809724509618 -3.05857142505209\\ --1.15355355249 -3.0594055914491\\ --1.12900985988383 -3.0316612426535\\ --1.10446616727766 -2.97068360146257\\ --1.07992247467149 -2.88584164144167\\ --1.05537878206532 -2.7788187463398\\ --1.03083508945915 -2.64179784593011\\ --0.957204011640641 -2.11741383173444\\ --0.932660319034468 -1.94697175864269\\ --0.908116626428303 -1.74913747055684\\ --0.88357293382213 -1.51630002589027\\ --0.859029241215957 -1.32388103733548\\ --0.834485548609791 -1.25547919459462\\ --0.785398163397446 -1.35535922330764\\ --0.76085447079128 -1.40105712246658\\ --0.736310778185107 -1.48314193528621\\ --0.711767085578934 -1.60767016561632\\ --0.687223392972768 -1.67551731596785\\ --0.662679700366596 -1.71494365777474\\ --0.63813600776043 -1.71820525815976\\ --0.613592315154257 -1.68776926339483\\ --0.589048622548084 -1.62532409404639\\ --0.564504929941918 -1.54010490273969\\ --0.539961237335746 -1.4164302592139\\ --0.490873852123407 -1.07552633714884\\ --0.441786466911061 -0.688310981739598\\ --0.417242774304896 -0.488474201410419\\ --0.392699081698723 -0.315746347742085\\ --0.343611696486384 -0.0494373636250245\\ --0.319068003880211 -0\\ --0.294524311274046 -0.0661029758684393\\ --0.269980618667873 -0.280784524800559\\ --0.2454369260617 -0.657474690551474\\ --0.220893233455534 -1.19458775500653\\ --0.196349540849361 -1.92980106861027\\ --0.171805848243189 -2.781939214681\\ --0.147262155637023 -3.82635324494866\\ --0.0981747704246843 -6.57941824337365\\ --0.0490873852123386 -9.47773091071146\\ --0.0245436926061728 -10.6809263718464\\ -0 -11.2450827557943\\ -0.0245436926061728 -10.6809263718464\\ -0.0490873852123386 -9.47773091071146\\ -0.0981747704246843 -6.57941824337366\\ -0.147262155637023 -3.82635324494866\\ -0.171805848243189 -2.781939214681\\ -0.196349540849361 -1.92980106861027\\ -0.220893233455534 -1.19458775500652\\ -0.2454369260617 -0.657474690551474\\ -0.269980618667873 -0.280784524800552\\ -0.294524311274046 -0.0661029758684322\\ -0.319068003880211 0\\ -0.343611696486384 -0.0494373636250245\\ -0.392699081698723 -0.315746347742085\\ -0.417242774304896 -0.488474201410419\\ -0.466330159517234 -0.886419690092346\\ -0.490873852123407 -1.07552633714884\\ -0.539961237335746 -1.4164302592139\\ -0.564504929941918 -1.54010490273969\\ -0.589048622548084 -1.62532409404639\\ -0.613592315154257 -1.68776926339483\\ -0.63813600776043 -1.71820525815976\\ -0.662679700366596 -1.71494365777474\\ -0.687223392972768 -1.67551731596784\\ -0.711767085578934 -1.60767016561632\\ -0.736310778185107 -1.48314193528621\\ -0.76085447079128 -1.40105712246658\\ -0.785398163397446 -1.35535922330764\\ -0.834485548609791 -1.25547919459462\\ -0.859029241215957 -1.32388103733548\\ -0.88357293382213 -1.51630002589027\\ -0.908116626428303 -1.74913747055684\\ -0.932660319034468 -1.94697175864269\\ -1.00629139685298 -2.46538205939333\\ -1.03083508945915 -2.64179784593011\\ -1.05537878206532 -2.7788187463398\\ -1.07992247467149 -2.88584164144167\\ -1.10446616727766 -2.97068360146258\\ -1.12900985988383 -3.0316612426535\\ -1.15355355249 -3.0594055914491\\ -1.17809724509618 -3.0585714250521\\ -1.22718463030851 -2.97707904052072\\ -1.25172832291468 -2.94778942364624\\ -1.27627201552085 -2.93615105708502\\ -1.30081570812703 -2.93351704789858\\ -1.32535940073319 -2.93820099699773\\ -1.34990309333936 -3.0070332942214\\ -1.37444678594554 -3.13389750127857\\ -1.3989904785517 -3.29683622342827\\ -1.42353417115788 -3.54761072032757\\ -1.47262155637021 -4.1192135361535\\ -1.49716524897639 -4.34815184803496\\ -1.52170894158255 -4.5187929199835\\ -1.54625263418873 -4.63831980162999\\ -1.5707963267949 -4.70301446670535\\ -1.59534001940106 -4.74564957733824\\ -1.61988371200724 -4.8134815299776\\ -1.64442740461341 -4.90272361408173\\ -1.66897109721958 -4.95636002488353\\ -1.69351478982575 -4.97451045806659\\ -1.71805848243192 -4.97303502588234\\ -1.74260217503809 -4.93802078574208\\ -1.76714586764426 -4.91128987148945\\ -1.79168956025043 -4.89778434539084\\ -1.8162332528566 -4.94933187405054\\ -1.84077694546277 -5.00995310954403\\ -1.86532063806894 -5.06241865677818\\ -1.88986433067511 -5.15834304528927\\ -1.91440802328128 -5.34213348629677\\ -1.93895171588745 -5.6349397663705\\ -1.96349540849362 -6.06771072445017\\ -1.98803910109979 -6.57390723520547\\ -2.01258279370596 -7.04574805161646\\ -2.03712648631213 -7.4271708098562\\ -2.06167017891831 -7.69653976428778\\ -2.08621387152447 -7.86197989534059\\ -2.11075756413064 -7.98175190194559\\ -2.13530125673681 -8.1165797444491\\ -2.15984494934298 -8.30596285747854\\ -2.18438864194916 -8.4380075354912\\ -2.20893233455532 -8.43416110047679\\ -2.23347602716149 -8.3659147804913\\ -2.25801971976767 -8.27290604595129\\ -2.28256341237383 -8.14161353993602\\ -2.30710710498001 -8.06093370603606\\ -2.33165079758618 -8.1409238489307\\ -2.35619449019234 -8.39313608791177\\ -2.38073818279852 -8.778725491267\\ -2.40528187540468 -9.31388042827889\\ -2.42982556801086 -10.1083695425263\\ -2.45436926061703 -11.0536074564346\\ -2.47891295322319 -11.8866214027661\\ -2.50345664582937 -12.4271267312005\\ -2.52800033843554 -12.6991459702061\\ -2.55254403104171 -12.8627077954076\\ -2.57708772364788 -13.0159869302563\\ -2.60163141625405 -13.2711055669692\\ -2.62617510886022 -13.7282789909322\\ -2.67526249407256 -14.9152364147404\\ -2.7243498792849 -15.9603331293506\\ -2.74889357189107 -16.4303665810851\\ -2.77343726449724 -16.8570972623589\\ -2.79798095710341 -17.3300455020857\\ -2.82252464970958 -17.9427012862682\\ -2.84706834231575 -18.7656037743951\\ -2.87161203492192 -19.8241749566727\\ -2.89615572752809 -21.0738850792815\\ -2.92069942013426 -22.423178321796\\ -2.94524311274043 -23.8596801342157\\ -2.9697868053466 -25.5045988241004\\ -2.99433049795277 -27.4518090423811\\ -3.01887419055894 -29.5850728981767\\ -3.04341788316511 -32.5498276313891\\ -3.06796157577129 -36.9286792174989\\ -3.09250526837745 -42.8433185127069\\ -3.11704896098362 -40.1613695561787\\ -3.1415926535898 -34.8799159666441\\ -}; -\addlegendentry{DB out19.2665} - -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/db_eq_wo_mpi.tex b/db_eq_wo_mpi.tex deleted file mode 100644 index 1bd7534..0000000 --- a/db_eq_wo_mpi.tex +++ /dev/null @@ -1,276 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.89020,0.10196,0.10980}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=-3.14159265358979, -xmax=3.14159265358979, -xlabel style={font=\color{white!15!black}}, -xlabel={Normalized Frequency}, -ymin=-46, -ymax=3, -ytick={-200, -190, -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, 0, 10}, -ylabel style={font=\color{white!15!black}}, -ylabel={normalized to 0 dB}, -axis background/.style={fill=white}, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, line width=1.0pt] - table[row sep=crcr]{% --3.11704896098362 -35.5782004188707\\ --3.09250526837745 -33.1159623086625\\ --3.06796157577129 -29.8127430785645\\ --3.04341788316511 -27.1142231619025\\ --3.01887419055894 -24.9816651036867\\ --2.99433049795277 -23.2550131042722\\ --2.9697868053466 -21.7690569330913\\ --2.94524311274043 -20.5282040877856\\ --2.92069942013426 -19.5466143865162\\ --2.87161203492192 -17.8570502294022\\ --2.84706834231575 -17.1174741970484\\ --2.82252464970958 -16.4882067469752\\ --2.79798095710341 -15.9631811263125\\ --2.74889357189107 -15.040897271394\\ --2.7243498792849 -14.4824420267243\\ --2.67526249407256 -13.1757573992517\\ --2.62617510886022 -11.8206968465478\\ --2.60163141625405 -11.3586194137695\\ --2.57708772364788 -11.1512196798002\\ --2.55254403104171 -11.1141125004655\\ --2.52800033843554 -11.1356970410682\\ --2.50345664582937 -11.1042663245222\\ --2.47891295322319 -10.8457113724973\\ --2.45436926061703 -10.2509043772106\\ --2.42982556801086 -9.49600909903207\\ --2.40528187540468 -8.91571719428563\\ --2.38073818279852 -8.56674653189375\\ --2.35619449019234 -8.30608957254529\\ --2.33165079758618 -8.07333298133048\\ --2.30710710498001 -7.90854344190689\\ --2.28256341237383 -7.81114175561396\\ --2.25801971976767 -7.72909129645249\\ --2.23347602716149 -7.62278081883213\\ --2.20893233455532 -7.50934135816258\\ --2.18438864194916 -7.34162072128382\\ --2.15984494934298 -7.05197027921345\\ --2.13530125673681 -6.72846162821838\\ --2.11075756413064 -6.504146636756\\ --2.06167017891831 -6.18679569976343\\ --2.03712648631213 -5.98544377852629\\ --2.01258279370596 -5.7268545940405\\ --1.96349540849362 -5.10207648230094\\ --1.93895171588745 -4.85548883097329\\ --1.91440802328128 -4.71795834646901\\ --1.88986433067511 -4.65821693591604\\ --1.86532063806894 -4.66014145162995\\ --1.84077694546277 -4.65493723917044\\ --1.8162332528566 -4.59055661230468\\ --1.79168956025043 -4.4864244064304\\ --1.76714586764426 -4.40468844343732\\ --1.74260217503809 -4.29729371979585\\ --1.71805848243192 -4.15868013907824\\ --1.69351478982575 -3.98304771525945\\ --1.66897109721958 -3.79412377848772\\ --1.61988371200724 -3.35829857637475\\ --1.59534001940106 -3.21155314163612\\ --1.5707963267949 -3.14335782104515\\ --1.54625263418873 -3.11025013724856\\ --1.49716524897639 -3.03771327815913\\ --1.47262155637021 -2.96542246404228\\ --1.44807786376405 -2.87345583737682\\ --1.42353417115788 -2.75279980788936\\ --1.3989904785517 -2.654987976207\\ --1.37444678594554 -2.58255627944738\\ --1.32535940073319 -2.47749537435604\\ --1.30081570812703 -2.42926024690468\\ --1.27627201552085 -2.36648968572744\\ --1.25172832291468 -2.28236363181344\\ --1.22718463030851 -2.18293152968466\\ --1.20264093770234 -2.05603615965727\\ --1.17809724509618 -1.93721440822181\\ --1.15355355249 -1.84295801281856\\ --1.12900985988383 -1.75506184318309\\ --1.07992247467149 -1.62153330633635\\ --1.05537878206532 -1.57859378742956\\ --1.03083508945915 -1.52956038827949\\ --1.00629139685298 -1.47648612994634\\ --0.932660319034468 -1.25222217345828\\ --0.908116626428303 -1.17388047239177\\ --0.88357293382213 -1.08991913238873\\ --0.859029241215957 -1.0262928345747\\ --0.834485548609791 -0.996923088744765\\ --0.809941856003618 -0.984189869128095\\ --0.785398163397446 -0.957970382685453\\ --0.76085447079128 -0.928971074953964\\ --0.736310778185107 -0.892174695809111\\ --0.711767085578934 -0.84622157240419\\ --0.63813600776043 -0.69126953432994\\ --0.589048622548084 -0.542550375291384\\ --0.564504929941918 -0.491672510477834\\ --0.539961237335746 -0.46643717780092\\ --0.515417544729573 -0.465110728576775\\ --0.490873852123407 -0.488012994046102\\ --0.466330159517234 -0.553875213284073\\ --0.441786466911061 -0.60431464496255\\ --0.417242774304896 -0.679993294821351\\ --0.392699081698723 -0.734482253211944\\ --0.368155389092557 -0.721399317000689\\ --0.343611696486384 -0.619598926472982\\ --0.294524311274046 -0.30630258882568\\ --0.269980618667873 -0.169900080060494\\ --0.2454369260617 -0.0760700467178523\\ --0.220893233455534 -0.0321032252202613\\ --0.171805848243189 -0\\ --0.147262155637023 -0.0160755308971048\\ --0.12271846303085 -0.0519964181031938\\ --0.0981747704246843 -0.156635723284822\\ --0.0245436926061728 -0.499771678339783\\ -0 -0.565174080829159\\ -0.0245436926061728 -0.499771678339776\\ -0.0490873852123386 -0.381706064715679\\ -0.12271846303085 -0.0519964181031867\\ -0.147262155637023 -0.0160755308971048\\ -0.171805848243189 0\\ -0.220893233455534 -0.0321032252202613\\ -0.2454369260617 -0.0760700467178523\\ -0.269980618667873 -0.169900080060494\\ -0.294524311274046 -0.30630258882568\\ -0.343611696486384 -0.619598926472982\\ -0.368155389092557 -0.721399317000689\\ -0.392699081698723 -0.734482253211951\\ -0.417242774304896 -0.679993294821351\\ -0.441786466911061 -0.60431464496255\\ -0.466330159517234 -0.553875213284073\\ -0.490873852123407 -0.488012994046102\\ -0.515417544729573 -0.465110728576775\\ -0.539961237335746 -0.466437177800927\\ -0.564504929941918 -0.491672510477834\\ -0.589048622548084 -0.542550375291384\\ -0.63813600776043 -0.69126953432994\\ -0.687223392972768 -0.795648160574636\\ -0.711767085578934 -0.846221572404183\\ -0.736310778185107 -0.892174695809111\\ -0.76085447079128 -0.928971074953964\\ -0.785398163397446 -0.957970382685453\\ -0.809941856003618 -0.984189869128095\\ -0.834485548609791 -0.996923088744765\\ -0.859029241215957 -1.0262928345747\\ -0.88357293382213 -1.08991913238873\\ -0.908116626428303 -1.17388047239177\\ -0.932660319034468 -1.25222217345828\\ -0.957204011640641 -1.32373537243189\\ -1.00629139685298 -1.47648612994634\\ -1.03083508945915 -1.52956038827949\\ -1.05537878206532 -1.57859378742956\\ -1.07992247467149 -1.62153330633635\\ -1.10446616727766 -1.68626503805518\\ -1.12900985988383 -1.75506184318309\\ -1.15355355249 -1.84295801281856\\ -1.17809724509618 -1.93721440822181\\ -1.20264093770234 -2.05603615965727\\ -1.22718463030851 -2.18293152968467\\ -1.25172832291468 -2.28236363181345\\ -1.27627201552085 -2.36648968572745\\ -1.30081570812703 -2.42926024690468\\ -1.32535940073319 -2.47749537435604\\ -1.37444678594554 -2.58255627944738\\ -1.3989904785517 -2.65498797620701\\ -1.42353417115788 -2.75279980788936\\ -1.44807786376405 -2.87345583737682\\ -1.47262155637021 -2.96542246404228\\ -1.49716524897639 -3.03771327815913\\ -1.54625263418873 -3.11025013724856\\ -1.5707963267949 -3.14335782104514\\ -1.59534001940106 -3.21155314163612\\ -1.61988371200724 -3.35829857637475\\ -1.66897109721958 -3.79412377848772\\ -1.69351478982575 -3.98304771525944\\ -1.71805848243192 -4.15868013907824\\ -1.74260217503809 -4.29729371979585\\ -1.76714586764426 -4.40468844343732\\ -1.79168956025043 -4.4864244064304\\ -1.8162332528566 -4.59055661230469\\ -1.84077694546277 -4.65493723917044\\ -1.86532063806894 -4.66014145162995\\ -1.88986433067511 -4.65821693591604\\ -1.91440802328128 -4.71795834646901\\ -1.93895171588745 -4.85548883097329\\ -1.96349540849362 -5.10207648230094\\ -2.01258279370596 -5.7268545940405\\ -2.03712648631213 -5.98544377852629\\ -2.06167017891831 -6.18679569976344\\ -2.11075756413064 -6.504146636756\\ -2.13530125673681 -6.72846162821838\\ -2.15984494934298 -7.05197027921345\\ -2.18438864194916 -7.34162072128382\\ -2.20893233455532 -7.50934135816258\\ -2.23347602716149 -7.62278081883213\\ -2.25801971976767 -7.72909129645249\\ -2.28256341237383 -7.81114175561396\\ -2.30710710498001 -7.90854344190689\\ -2.33165079758618 -8.07333298133048\\ -2.35619449019234 -8.30608957254529\\ -2.38073818279852 -8.56674653189375\\ -2.40528187540468 -8.91571719428563\\ -2.42982556801086 -9.49600909903207\\ -2.45436926061703 -10.2509043772106\\ -2.47891295322319 -10.8457113724973\\ -2.50345664582937 -11.1042663245222\\ -2.52800033843554 -11.1356970410682\\ -2.55254403104171 -11.1141125004655\\ -2.57708772364788 -11.1512196798002\\ -2.60163141625405 -11.3586194137695\\ -2.62617510886022 -11.8206968465478\\ -2.7243498792849 -14.4824420267244\\ -2.74889357189107 -15.0408972714706\\ -2.79798095710341 -15.9631811263036\\ -2.82252464970958 -16.4882067465251\\ -2.84706834231575 -17.1174741963807\\ -2.87161203492192 -17.8570490225173\\ -2.89615572752809 -18.6774208577484\\ -2.92069942013426 -19.5466157773339\\ -2.94524311274043 -20.5282137117928\\ -2.9697868053466 -21.7690828912817\\ -2.99433049795277 -23.3639330048926\\ -3.01887419055894 -25.1309853229038\\ -3.04341788316511 -27.3374155587587\\ -3.06796157577129 -30.2196680996993\\ -3.11704896098362 -37.8881022767508\\ -3.1415926535898 -35.937686895609\\ -}; -\addlegendentry{DB out47.1757} - -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/db_noise_mpi.tex b/db_noise_mpi.tex deleted file mode 100644 index a5b0a99..0000000 --- a/db_noise_mpi.tex +++ /dev/null @@ -1,295 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.89020,0.10196,0.10980}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=-3.14159265358979, -xmax=3.14159265358979, -xlabel style={font=\color{white!15!black}}, -xlabel={Normalized Frequency}, -ymin=-35, -ymax=0, -ytick={-200, -190, -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, 0, 10}, -ylabel style={font=\color{white!15!black}}, -ylabel={normalized to 0 dB}, -axis background/.style={fill=white}, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -xminorgrids, -ymajorgrids, -yminorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, line width=1.0pt] - table[row sep=crcr]{% --3.11704896098362 -34.3131450488072\\ --3.09250526837745 -22.267196196234\\ --3.06796157577129 -19.6346895905463\\ --3.04341788316511 -18.1952524397801\\ --3.01887419055894 -17.2592174472064\\ --2.99433049795277 -16.5769279469376\\ --2.9697868053466 -16.090951771503\\ --2.94524311274043 -16.0046100828047\\ --2.92069942013426 -15.8418247678835\\ --2.89615572752809 -15.3149223521918\\ --2.87161203492192 -14.658730543711\\ --2.84706834231575 -14.1277333218487\\ --2.82252464970958 -13.7205707193609\\ --2.79798095710341 -13.3952353522632\\ --2.77343726449724 -13.1831608890304\\ --2.7243498792849 -12.9357026724654\\ --2.69980618667873 -12.7853157461907\\ --2.67526249407256 -12.6608293199766\\ --2.65071880146639 -12.5994351134766\\ --2.62617510886022 -12.5594134618066\\ --2.60163141625405 -12.252405861374\\ --2.55254403104171 -10.9940967498421\\ --2.52800033843554 -10.5275867823918\\ --2.50345664582937 -10.4307919970419\\ --2.47891295322319 -10.7441236244153\\ --2.45436926061703 -11.3443158297057\\ --2.42982556801086 -11.9038524771046\\ --2.40528187540468 -11.8977758894782\\ --2.38073818279852 -11.4032305242715\\ --2.35619449019234 -10.8206876678612\\ --2.33165079758618 -10.3655775288927\\ --2.30710710498001 -10.1411502371605\\ --2.28256341237383 -10.0275725518735\\ --2.25801971976767 -9.79947146240389\\ --2.23347602716149 -9.44254273389932\\ --2.18438864194916 -8.66113441860007\\ --2.15984494934298 -8.32312800793783\\ --2.11075756413064 -7.79280902100031\\ --2.08621387152447 -7.45195580784125\\ --2.06167017891831 -7.18469013477623\\ --2.03712648631213 -7.11040672526116\\ --2.01258279370596 -7.22639646388401\\ --1.98803910109979 -7.51517990964668\\ --1.96349540849362 -7.93800563912671\\ --1.93895171588745 -8.29828148114878\\ --1.91440802328128 -8.387179482289\\ --1.88986433067511 -8.28530306362875\\ --1.86532063806894 -8.20282444470519\\ --1.84077694546277 -8.19381257640935\\ --1.8162332528566 -8.1599225730401\\ --1.79168956025043 -8.01820487442049\\ --1.76714586764426 -7.56130073272246\\ --1.74260217503809 -7.14061573945742\\ --1.71805848243192 -6.62682673757766\\ --1.69351478982575 -6.19223388107344\\ --1.66897109721958 -5.90625549009543\\ --1.64442740461341 -5.74369686649744\\ --1.61988371200724 -5.70472998208211\\ --1.59534001940106 -5.63935449974836\\ --1.5707963267949 -5.55146369024497\\ --1.54625263418873 -5.55135711200268\\ --1.52170894158255 -5.61443959310917\\ --1.49716524897639 -5.72500445090551\\ --1.47262155637021 -5.93402555559094\\ --1.44807786376405 -6.24769554324589\\ --1.42353417115788 -6.51551248033976\\ --1.3989904785517 -6.74232519069472\\ --1.37444678594554 -6.77048169178611\\ --1.34990309333936 -6.67391454327632\\ --1.32535940073319 -6.51628877937085\\ --1.27627201552085 -6.1030106496908\\ --1.25172832291468 -5.93485117988067\\ --1.22718463030851 -5.87756181550613\\ --1.20264093770234 -5.85961739672202\\ --1.17809724509618 -5.83345817542033\\ --1.15355355249 -5.78901638459508\\ --1.12900985988383 -5.68962723876609\\ --1.10446616727766 -5.54337665236435\\ --1.07992247467149 -5.36856900781121\\ --1.05537878206532 -5.21670034258733\\ --1.03083508945915 -5.10731269634078\\ --1.00629139685298 -5.01734118293459\\ --0.981747704246807 -4.97536935522933\\ --0.957204011640641 -4.97971773581759\\ --0.932660319034468 -5.034237466321\\ --0.908116626428303 -5.09928298231328\\ --0.88357293382213 -5.12622376596804\\ --0.859029241215957 -5.12356760360715\\ --0.834485548609791 -5.18926715032397\\ --0.809941856003618 -5.24776542972374\\ --0.785398163397446 -5.3398222380389\\ --0.76085447079128 -5.36523740936401\\ --0.736310778185107 -5.26486466619456\\ --0.711767085578934 -5.0551647745266\\ --0.687223392972768 -4.7404255947558\\ --0.662679700366596 -4.32316600023172\\ --0.63813600776043 -4.06213468290632\\ --0.613592315154257 -3.93585700038375\\ --0.589048622548084 -3.93578572547992\\ --0.564504929941918 -4.09417112434627\\ --0.539961237335746 -4.44194577474517\\ --0.515417544729573 -4.75916484246466\\ --0.490873852123407 -4.93749189095814\\ --0.466330159517234 -5.05192489877623\\ --0.441786466911061 -4.99827294144359\\ --0.417242774304896 -4.82034500119954\\ --0.392699081698723 -4.53631000669057\\ --0.368155389092557 -4.16237685284171\\ --0.343611696486384 -3.71750617836146\\ --0.319068003880211 -3.22184120926914\\ --0.171805848243189 -0\\ --0.147262155637023 -2.42164758505762\\ --0.12271846303085 -2.55785798440041\\ --0.0981747704246843 -2.39339347291558\\ --0.0736310778185114 -1.97663231386586\\ --0.0490873852123386 -1.70870310785322\\ --0.0245436926061728 -1.48162490657379\\ -0 -1.38410632608296\\ -0.0245436926061728 -1.48162490657379\\ -0.0490873852123386 -1.70870310785322\\ -0.0736310778185114 -1.97663231386586\\ -0.0981747704246843 -2.39339347291558\\ -0.12271846303085 -2.55785798440041\\ -0.147262155637023 -2.42164758505762\\ -0.171805848243189 0\\ -0.220893233455534 -1.05640831862885\\ -0.319068003880211 -3.22184120926914\\ -0.343611696486384 -3.71750617836146\\ -0.368155389092557 -4.16237685284171\\ -0.392699081698723 -4.53631000669057\\ -0.417242774304896 -4.82034500119954\\ -0.441786466911061 -4.99827294144359\\ -0.466330159517234 -5.05192489877624\\ -0.490873852123407 -4.93749189095814\\ -0.515417544729573 -4.75916484246466\\ -0.539961237335746 -4.44194577474517\\ -0.564504929941918 -4.09417112434627\\ -0.589048622548084 -3.93578572547992\\ -0.613592315154257 -3.93585700038375\\ -0.63813600776043 -4.06213468290632\\ -0.662679700366596 -4.32316600023172\\ -0.687223392972768 -4.7404255947558\\ -0.711767085578934 -5.05516477452661\\ -0.736310778185107 -5.26486466619456\\ -0.76085447079128 -5.36523740936401\\ -0.785398163397446 -5.3398222380389\\ -0.809941856003618 -5.24776542972374\\ -0.834485548609791 -5.18926715032396\\ -0.859029241215957 -5.12356760360715\\ -0.88357293382213 -5.12622376596804\\ -0.908116626428303 -5.09928298231328\\ -0.932660319034468 -5.034237466321\\ -0.957204011640641 -4.97971773581759\\ -0.981747704246807 -4.97536935522933\\ -1.00629139685298 -5.01734118293459\\ -1.03083508945915 -5.10731269634078\\ -1.05537878206532 -5.21670034258733\\ -1.07992247467149 -5.36856900781121\\ -1.10446616727766 -5.54337665236435\\ -1.12900985988383 -5.68962723876609\\ -1.15355355249 -5.78901638459508\\ -1.17809724509618 -5.83345817542033\\ -1.20264093770234 -5.85961739672201\\ -1.22718463030851 -5.87756181550613\\ -1.25172832291468 -5.93485117988067\\ -1.27627201552085 -6.10301064969081\\ -1.32535940073319 -6.51628877937085\\ -1.34990309333936 -6.67391454327632\\ -1.37444678594554 -6.77048169178612\\ -1.3989904785517 -6.74232519069473\\ -1.42353417115788 -6.51551248033977\\ -1.44807786376405 -6.24769554324589\\ -1.47262155637021 -5.93402555559094\\ -1.49716524897639 -5.72500445090551\\ -1.52170894158255 -5.61443959310918\\ -1.54625263418873 -5.55135711200268\\ -1.5707963267949 -5.55146369024497\\ -1.59534001940106 -5.63935449974836\\ -1.61988371200724 -5.7047299820821\\ -1.64442740461341 -5.74369686649744\\ -1.66897109721958 -5.90625549009542\\ -1.69351478982575 -6.19223388107344\\ -1.71805848243192 -6.62682673757765\\ -1.74260217503809 -7.14061573945742\\ -1.76714586764426 -7.56130073272246\\ -1.79168956025043 -8.01820487442049\\ -1.8162332528566 -8.1599225730401\\ -1.84077694546277 -8.19381257640935\\ -1.86532063806894 -8.20282444470519\\ -1.88986433067511 -8.28530306362875\\ -1.91440802328128 -8.387179482289\\ -1.93895171588745 -8.29828148114878\\ -1.96349540849362 -7.93800563912671\\ -1.98803910109979 -7.51517990964668\\ -2.01258279370596 -7.22639646388401\\ -2.03712648631213 -7.11040672526116\\ -2.06167017891831 -7.18469013477623\\ -2.08621387152447 -7.45195580784125\\ -2.11075756413064 -7.79280902100031\\ -2.15984494934298 -8.32312800793783\\ -2.18438864194916 -8.66113441860008\\ -2.23347602716149 -9.44254273389932\\ -2.25801971976767 -9.79947146240389\\ -2.28256341237383 -10.0275725518735\\ -2.30710710498001 -10.1411502371605\\ -2.33165079758618 -10.3655775288927\\ -2.35619449019234 -10.8206876678612\\ -2.38073818279852 -11.4032305242715\\ -2.40528187540468 -11.8977758894782\\ -2.42982556801086 -11.9038524771046\\ -2.45436926061703 -11.3443158297057\\ -2.47891295322319 -10.7441236244153\\ -2.50345664582937 -10.4307919970419\\ -2.52800033843554 -10.5275867823917\\ -2.55254403104171 -10.9940967498419\\ -2.60163141625405 -12.2524058613756\\ -2.62617510886022 -12.5594134617074\\ -2.65071880146639 -12.5994351136522\\ -2.67526249407256 -12.660829319499\\ -2.69980618667873 -12.7853157436709\\ -2.7243498792849 -12.9357026694219\\ -2.77343726449724 -13.1831605981046\\ -2.79798095710341 -13.3952355524471\\ -2.82252464970958 -13.7205723063792\\ -2.84706834231575 -14.1277364158962\\ -2.87161203492192 -14.6591344197684\\ -2.89615572752809 -15.3153254629515\\ -2.92069942013426 -15.8413568119397\\ -2.94524311274043 -16.0023943536069\\ -2.9697868053466 -16.0874143228353\\ -2.99433049795277 -16.4203948950371\\ -3.01887419055894 -17.2198129812753\\ -3.04341788316511 -18.151481900993\\ -3.06796157577129 -19.4062059756628\\ -3.09250526837745 -21.3473313091987\\ -3.11704896098362 -25.248496420222\\ -3.1415926535898 -28.3767847971192\\ -}; -\addlegendentry{DB Noise19.2665} - -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/db_noise_wo_mpi.tex b/db_noise_wo_mpi.tex deleted file mode 100644 index 386de01..0000000 --- a/db_noise_wo_mpi.tex +++ /dev/null @@ -1,299 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.89020,0.10196,0.10980}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=-3.14159265358979, -xmax=3.14159265358979, -xlabel style={font=\color{white!15!black}}, -xlabel={Normalized Frequency}, -ymin=-35, -ymax=3, -ytick={-200, -190, -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, 0, 10}, -ylabel style={font=\color{white!15!black}}, -ylabel={normalized to 0 dB}, -axis background/.style={fill=white}, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, line width=1.0pt] - table[row sep=crcr]{% --3.11704896098362 -29.56690412476\\ --3.09250526837745 -25.3644918186209\\ --3.06796157577128 -22.30730387375\\ --3.04341788316511 -19.9954524619813\\ --3.01887419055894 -18.1507513447907\\ --2.99433049795277 -16.6076585312891\\ --2.9697868053466 -15.2461686465389\\ --2.94524311274043 -14.2059915088232\\ --2.92069942013426 -13.4872968374207\\ --2.89615572752809 -12.7053099196834\\ --2.87161203492192 -11.7799752503431\\ --2.84706834231575 -10.9157197897258\\ --2.82252464970958 -10.2283939059761\\ --2.79798095710341 -9.76811722848216\\ --2.77343726449724 -9.60018105035478\\ --2.74889357189107 -9.63373286010098\\ --2.7243498792849 -9.59587490688709\\ --2.69980618667873 -9.37254772114989\\ --2.67526249407256 -9.05870610749954\\ --2.62617510886022 -8.52456927054195\\ --2.60163141625405 -8.03921949291331\\ --2.55254403104171 -6.68995050377789\\ --2.52800033843554 -6.25353078740822\\ --2.50345664582937 -6.19551569975192\\ --2.4789129532232 -6.59545901902654\\ --2.45436926061702 -7.30521855386077\\ --2.42982556801086 -7.85202206428982\\ --2.40528187540469 -7.71940845485185\\ --2.38073818279852 -6.98988271739371\\ --2.35619449019234 -6.05737033896411\\ --2.33165079758617 -5.21147393956923\\ --2.30710710498001 -4.65553527546583\\ --2.28256341237383 -4.37497436709315\\ --2.25801971976766 -4.24445427323096\\ --2.23347602716149 -4.23783848068609\\ --2.20893233455532 -4.38974561023634\\ --2.18438864194915 -4.64227723733761\\ --2.15984494934298 -4.87939584637504\\ --2.13530125673681 -5.06102058647945\\ --2.11075756413064 -5.1115797662322\\ --2.08621387152447 -4.74443552790122\\ --2.0616701789183 -4.11252781856745\\ --2.03712648631213 -3.57844099840829\\ --2.01258279370596 -3.15461107678053\\ --1.98803910109979 -2.97187224999008\\ --1.96349540849362 -3.11854439147683\\ --1.93895171588745 -3.32783807306128\\ --1.91440802328128 -3.42392975582494\\ --1.88986433067511 -3.42557304147892\\ --1.86532063806894 -3.36394467547953\\ --1.84077694546277 -3.30855026424176\\ --1.8162332528566 -3.14790250068943\\ --1.79168956025043 -2.92004953531518\\ --1.76714586764426 -2.66565529315556\\ --1.74260217503809 -2.38358723758726\\ --1.71805848243192 -2.21108638851551\\ --1.69351478982575 -2.22382786445652\\ --1.66897109721958 -2.43174036822529\\ --1.61988371200724 -3.20868918272751\\ --1.59534001940107 -3.40804148700824\\ --1.5707963267949 -3.46769295384922\\ --1.54625263418873 -3.44256929870861\\ --1.52170894158256 -3.34829866588534\\ --1.49716524897639 -3.18823276160444\\ --1.47262155637021 -3.0096158207128\\ --1.44807786376404 -2.80196796486164\\ --1.42353417115788 -2.57991209356132\\ --1.39899047855171 -2.39324891004939\\ --1.37444678594553 -2.17497178218852\\ --1.34990309333936 -1.9815178598944\\ --1.32535940073319 -1.86783751695322\\ --1.30081570812703 -1.86688379492939\\ --1.27627201552085 -1.87464022701403\\ --1.25172832291468 -1.82812211345248\\ --1.22718463030851 -1.78495277610481\\ --1.20264093770234 -1.80770510184558\\ --1.15355355249 -2.01822512349233\\ --1.12900985988383 -2.0104138728127\\ --1.10446616727766 -1.9854246410849\\ --1.07992247467149 -1.83098330554181\\ --1.05537878206532 -1.40389512308032\\ --1.03083508945915 -1.01656520978779\\ --1.00629139685298 -0.81242159058003\\ --0.981747704246811 -0.714551381103277\\ --0.957204011640641 -0.751649983982947\\ --0.908116626428299 -0.96939431010497\\ --0.88357293382213 -1.02782313519112\\ --0.859029241215961 -1.02764295098685\\ --0.834485548609788 -1.04303118195184\\ --0.809941856003618 -1.1135874216063\\ --0.785398163397449 -1.21428662741738\\ --0.760854470791276 -1.3250286832735\\ --0.736310778185107 -1.37763336808698\\ --0.711767085578938 -1.27527840883845\\ --0.687223392972768 -1.08192664495025\\ --0.662679700366596 -0.707175116884688\\ --0.638136007760426 -0.440848611322355\\ --0.613592315154257 -0.317627491607571\\ --0.589048622548088 -0.368550433609716\\ --0.564504929941915 -0.529567019701872\\ --0.539961237335746 -0.740023137301691\\ --0.515417544729576 -0.936949534039805\\ --0.490873852123404 -1.08380683423007\\ --0.466330159517234 -1.14951693986952\\ --0.441786466911065 -1.16653296678408\\ --0.417242774304896 -1.12681254908156\\ --0.392699081698723 -1.04344044810478\\ --0.368155389092554 -0.911358559656215\\ --0.343611696486384 -0.673593283068104\\ --0.319068003880215 -0.378671203309167\\ --0.294524311274042 -0.147237291038302\\ --0.269980618667873 -0.0687611272534738\\ --0.245436926061704 -0.0284356029270683\\ --0.220893233455531 -0.00158982689712062\\ --0.196349540849361 -3.5527136788005e-15\\ --0.171805848243192 -0.0290183239765689\\ --0.147262155637023 -0.0677220011932569\\ --0.12271846303085 -0.0755749861006834\\ --0.0736310778185114 -0.150623061280683\\ --0.0490873852123421 -0.150293248571142\\ --0.0245436926061693 -0.075910244951956\\ -0 -0.129653251125745\\ -0.0245436926061693 -0.0759102449519595\\ -0.0490873852123421 -0.150293248571142\\ -0.0736310778185114 -0.150623061280683\\ -0.12271846303085 -0.0755749861006869\\ -0.147262155637023 -0.0677220011932569\\ -0.171805848243192 -0.0290183239765689\\ -0.196349540849361 0\\ -0.220893233455531 -0.00158982689712062\\ -0.245436926061704 -0.0284356029270718\\ -0.269980618667873 -0.0687611272534738\\ -0.294524311274042 -0.147237291038305\\ -0.319068003880215 -0.378671203309167\\ -0.343611696486384 -0.673593283068108\\ -0.368155389092554 -0.911358559656218\\ -0.392699081698723 -1.04344044810479\\ -0.417242774304896 -1.12681254908156\\ -0.441786466911065 -1.16653296678408\\ -0.466330159517234 -1.14951693986952\\ -0.490873852123404 -1.08380683423007\\ -0.515417544729576 -0.936949534039805\\ -0.539961237335746 -0.740023137301687\\ -0.564504929941915 -0.529567019701869\\ -0.589048622548088 -0.36855043360972\\ -0.613592315154257 -0.317627491607574\\ -0.638136007760426 -0.440848611322359\\ -0.662679700366596 -0.707175116884692\\ -0.687223392972768 -1.08192664495025\\ -0.711767085578938 -1.27527840883845\\ -0.736310778185107 -1.37763336808698\\ -0.760854470791276 -1.3250286832735\\ -0.785398163397449 -1.21428662741738\\ -0.809941856003618 -1.1135874216063\\ -0.834485548609788 -1.04303118195183\\ -0.859029241215961 -1.02764295098685\\ -0.88357293382213 -1.02782313519112\\ -0.908116626428299 -0.969394310104974\\ -0.957204011640641 -0.751649983982947\\ -0.981747704246811 -0.714551381103277\\ -1.00629139685298 -0.81242159058003\\ -1.03083508945915 -1.01656520978779\\ -1.05537878206532 -1.40389512308032\\ -1.07992247467149 -1.83098330554182\\ -1.10446616727766 -1.9854246410849\\ -1.12900985988383 -2.0104138728127\\ -1.15355355249 -2.01822512349233\\ -1.20264093770234 -1.80770510184558\\ -1.22718463030851 -1.78495277610481\\ -1.25172832291468 -1.82812211345248\\ -1.27627201552085 -1.87464022701403\\ -1.30081570812703 -1.86688379492939\\ -1.32535940073319 -1.86783751695322\\ -1.34990309333936 -1.98151785989441\\ -1.37444678594553 -2.17497178218852\\ -1.39899047855171 -2.3932489100494\\ -1.42353417115788 -2.57991209356132\\ -1.44807786376404 -2.80196796486164\\ -1.47262155637021 -3.0096158207128\\ -1.49716524897639 -3.18823276160444\\ -1.52170894158256 -3.34829866588535\\ -1.54625263418873 -3.44256929870861\\ -1.5707963267949 -3.46769295384922\\ -1.59534001940107 -3.40804148700824\\ -1.61988371200724 -3.20868918272751\\ -1.66897109721958 -2.43174036822529\\ -1.69351478982575 -2.22382786445652\\ -1.71805848243192 -2.21108638851551\\ -1.74260217503809 -2.38358723758726\\ -1.76714586764426 -2.66565529315556\\ -1.79168956025043 -2.92004953531518\\ -1.8162332528566 -3.14790250068943\\ -1.84077694546277 -3.30855026424176\\ -1.86532063806894 -3.36394467547953\\ -1.88986433067511 -3.42557304147892\\ -1.91440802328128 -3.42392975582495\\ -1.93895171588745 -3.32783807306128\\ -1.96349540849362 -3.11854439147683\\ -1.98803910109979 -2.97187224999008\\ -2.01258279370596 -3.15461107678053\\ -2.03712648631213 -3.57844099840829\\ -2.0616701789183 -4.11252781856745\\ -2.08621387152447 -4.74443552790122\\ -2.11075756413064 -5.1115797662322\\ -2.13530125673681 -5.06102058647945\\ -2.15984494934298 -4.87939584637504\\ -2.18438864194915 -4.64227723733761\\ -2.20893233455532 -4.38974561023634\\ -2.23347602716149 -4.23783848068609\\ -2.25801971976766 -4.24445427323096\\ -2.28256341237383 -4.37497436709315\\ -2.30710710498001 -4.65553527546583\\ -2.33165079758617 -5.21147393956922\\ -2.35619449019234 -6.05737033896411\\ -2.38073818279852 -6.98988271739371\\ -2.40528187540469 -7.71940845485185\\ -2.42982556801086 -7.85202206428983\\ -2.45436926061702 -7.30521855386077\\ -2.4789129532232 -6.59545901902653\\ -2.50345664582937 -6.19551569975192\\ -2.52800033843554 -6.25353078740822\\ -2.55254403104171 -6.68995050377788\\ -2.60163141625405 -8.03921949291331\\ -2.62617510886022 -8.52456927054182\\ -2.67526249407256 -9.05870610750129\\ -2.69980618667873 -9.37254772115121\\ -2.7243498792849 -9.59587490688876\\ -2.74889357189107 -9.63373286090274\\ -2.77343726449724 -9.60018105054644\\ -2.79798095710341 -9.76811722663992\\ -2.82252464970958 -10.2283939034122\\ -2.84706834231575 -10.9157197856076\\ -2.87161203492192 -11.7799747002882\\ -2.89615572752809 -12.7053120008311\\ -2.92069942013426 -13.4872977067247\\ -2.94524311274043 -14.2060001490953\\ -2.9697868053466 -15.246186526982\\ -3.01887419055894 -18.4109510569831\\ -3.04341788316511 -20.3062518390902\\ -3.06796157577128 -22.6467871973893\\ -3.09250526837745 -25.6049717256354\\ -3.11704896098362 -29.0319196411313\\ -3.14159265358979 -30.3572678405229\\ -}; -\addlegendentry{DB Noise54.075} - -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/pam6_db.tex b/pam6_db.tex deleted file mode 100644 index 6ebeaf2..0000000 --- a/pam6_db.tex +++ /dev/null @@ -1,186 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.90471,0.19176,0.19882}% -\definecolor{mycolor2}{rgb}{0.29412,0.54471,0.74941}% -\definecolor{mycolor3}{rgb}{0.37176,0.71765,0.36118}% -\definecolor{mycolor4}{rgb}{1.00000,0.54824,0.10000}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=15, -xmax=40, -xlabel style={font=\color{white!15!black}}, -xlabel={Received Optical Power (dBm)}, -ymode=log, -ymin=0.001, -ymax=1, -yminorticks=true, -ylabel style={font=\color{white!15!black}}, -ylabel={Bit Error Rate (BER)}, -axis background/.style={fill=white}, -title style={font=\bfseries}, -title={Bit Error Rate vs. ROP}, -xmajorgrids, -xminorgrids, -ymajorgrids, -yminorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, mark size=2.5pt, mark=*, mark options={solid, mycolor1}] - table[row sep=crcr]{% -15 0.327010199014477\\ -16 0.311702995808577\\ -17 0.302976362038969\\ -18 0.290172900555268\\ -19 0.275210526133021\\ -20 0.263951328094344\\ -21 0.253598824873511\\ -22 0.239834843333831\\ -23 0.222991710913327\\ -24 0.213765370578083\\ -25 0.187866749545958\\ -26 0.171604235178092\\ -27 0.15502015841983\\ -28 0.131515892335633\\ -29 0.118871823008727\\ -30 0.0915567300646945\\ -31 0.0811198427608527\\ -32 0.0718601655039258\\ -33 0.0635054467668395\\ -34 0.0547899253044598\\ -35 0.029896620816824\\ -36 0.0124562018828416\\ -37 0.00786577721907566\\ -38 0.00456715827050829\\ -39 0.00261799013088214\\ -40 0.00153766551260726\\ -}; -\addlegendentry{VNLE Lw: 0.5 MHz} - -\addplot [color=mycolor2, mark size=2.5pt, mark=*, mark options={solid, mycolor2}] - table[row sep=crcr]{% -15 0\\ -16 0\\ -17 0\\ -18 0\\ -19 0\\ -20 0\\ -21 0\\ -22 0\\ -23 0\\ -24 0\\ -25 0\\ -26 0\\ -27 0\\ -28 0\\ -29 0\\ -30 0\\ -31 0\\ -32 0\\ -33 0\\ -34 0\\ -35 0\\ -36 0\\ -37 0\\ -38 0\\ -39 0\\ -40 0\\ -}; -\addlegendentry{MLSE 1 Lw: 0.5 MHz} - -\addplot [color=mycolor3, mark size=2.5pt, mark=*, mark options={solid, mycolor3}] - table[row sep=crcr]{% -15 0\\ -16 0\\ -17 0\\ -18 0\\ -19 0\\ -20 0\\ -21 0\\ -22 0\\ -23 0\\ -24 0\\ -25 0\\ -26 0\\ -27 0\\ -28 0\\ -29 0\\ -30 0\\ -31 0\\ -32 0\\ -33 0\\ -34 0\\ -35 0\\ -36 0\\ -37 0\\ -38 0\\ -39 0\\ -40 0\\ -}; -\addlegendentry{MLSE 2Lw: 0.5 MHz} - -\addplot [color=mycolor4, mark size=2.5pt, mark=*, mark options={solid, mycolor4}] - table[row sep=crcr]{% -15 0\\ -16 0\\ -17 0\\ -18 0\\ -19 0\\ -20 0\\ -21 0\\ -22 0\\ -23 0\\ -24 0\\ -25 0\\ -26 0\\ -27 0\\ -28 0\\ -29 0\\ -30 0\\ -31 0\\ -32 0\\ -33 0\\ -34 0\\ -35 0\\ -36 0\\ -37 0\\ -38 0\\ -39 0\\ -40 0\\ -}; -\addlegendentry{MLSE 3Lw: 0.5 MHz} - -\addplot [color=white!15!black, dashed, forget plot] - table[row sep=crcr]{% -15 0.0038\\ -40 0.0038\\ -}; -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/pam6_pf.tex b/pam6_pf.tex deleted file mode 100644 index 190cf44..0000000 --- a/pam6_pf.tex +++ /dev/null @@ -1,196 +0,0 @@ -% This file was created by matlab2tikz. -% -%The latest updates can be retrieved from -% http://www.mathworks.com/matlabcentral/fileexchange/22022-matlab2tikz-matlab2tikz -%where you can also make suggestions and rate matlab2tikz. -% -\definecolor{mycolor1}{rgb}{0.90471,0.19176,0.19882}% -\definecolor{mycolor2}{rgb}{0.29412,0.54471,0.74941}% -\definecolor{mycolor3}{rgb}{0.37176,0.71765,0.36118}% -\definecolor{mycolor4}{rgb}{1.00000,0.54824,0.10000}% -% -\begin{tikzpicture} - -\begin{axis}[% -width=0.951\fwidth, -height=\fheight, -at={(0\fwidth,0\fheight)}, -scale only axis, -xmin=15, -xmax=40, -xlabel style={font=\color{white!15!black}}, -xlabel={Received Optical Power (dBm)}, -ymode=log, -ymin=0.00059902281148318, -ymax=0.166016828200258, -yminorticks=true, -ylabel style={font=\color{white!15!black}}, -ylabel={Bit Error Rate (BER)}, -axis background/.style={fill=white}, -title style={font=\bfseries}, -title={Bit Error Rate vs. ROP}, -xmajorgrids, -xminorgrids, -ymajorgrids, -yminorgrids, -legend style={legend cell align=left, align=left, draw=white!15!black} -] -\addplot [color=mycolor1, line width=2.0pt, mark size=2.5pt, mark=*, mark options={solid, mycolor1}] - table[row sep=crcr]{% -15 0.16008493969837\\ -16 0.148018710347294\\ -17 0.135397560154044\\ -18 0.118006452083384\\ -19 0.094911952328202\\ -20 0.0850855474026718\\ -21 0.0778479628015516\\ -22 0.0688008084203508\\ -23 0.0471981359104626\\ -24 0.0323975844622164\\ -25 0.0267066941233258\\ -26 0.0216530251520129\\ -27 0.0173115856220635\\ -28 0.0136604981786234\\ -29 0.010617115036688\\ -30 0.00803767072150127\\ -31 0.00594925148193035\\ -32 0.00430393549305654\\ -33 0.00307915088082398\\ -34 0.0022804537988464\\ -35 0.00167379127614431\\ -36 0.00127305369675208\\ -37 0.00100184394848057\\ -38 0.000819185398428303\\ -39 0.000686879490500714\\ -40 0.00059902281148318\\ -}; -\addlegendentry{VNLE Lw: 0.5 MHz} - -\addplot [color=mycolor2, line width=2.0pt, mark size=2.5pt, mark=*, mark options={solid, mycolor2}] - table[row sep=crcr]{% -15 0.166016828200258\\ -16 0.153631814535592\\ -17 0.139560160989551\\ -18 0.1207188968257\\ -19 0.0955255600429213\\ -20 0.0862474780271488\\ -21 0.0794370227350861\\ -22 0.0710753588059826\\ -23 0.0479850261660109\\ -24 0.0336824449853977\\ -25 0.0294278203556633\\ -26 0.0260795432841729\\ -27 0.0232222912882984\\ -28 0.0207911268226788\\ -29 0.0185690126367769\\ -30 0.016517750174498\\ -31 0.0147147783268338\\ -32 0.0131875306022523\\ -33 0.0116262514367866\\ -34 0.0100031600623678\\ -35 0.00841236383082901\\ -36 0.00697852893887884\\ -37 0.00572492177977491\\ -38 0.00470189499564189\\ -39 0.00391639377849699\\ -40 0.00331771822661467\\ -}; -\addlegendentry{MLSE 1 Lw: 0.5 MHz} - -\addplot [color=mycolor3, line width=2.0pt, mark size=2.5pt, mark=*, mark options={solid, mycolor3}] - table[row sep=crcr]{% -15 0.163486347488792\\ -16 0.149813695224139\\ -17 0.13425299250961\\ -18 0.112261041987158\\ -19 0.082994350086294\\ -20 0.0737412707617834\\ -21 0.0671634794022968\\ -22 0.0587726456667211\\ -23 0.0332261458698679\\ -24 0.018219322218711\\ -25 0.0151498946067111\\ -26 0.0126402494712973\\ -27 0.0107778962318861\\ -28 0.00934718667634363\\ -29 0.00803975427910643\\ -30 0.00699832273612785\\ -31 0.00608711354347169\\ -32 0.00526619184703909\\ -33 0.00455535144407905\\ -34 0.00383096791668548\\ -35 0.00322361087478166\\ -36 0.00270202695429022\\ -37 0.00228288461605242\\ -38 0.00194291746681066\\ -39 0.001689417958183\\ -40 0.00148696561088173\\ -}; -\addlegendentry{MLSE 2Lw: 0.5 MHz} - -\addplot [color=mycolor4, line width=2.0pt, mark size=2.5pt, mark=*, mark options={solid, mycolor4}] - table[row sep=crcr]{% -15 0.162657786081141\\ -16 0.149052154919453\\ -17 0.132976813476451\\ -18 0.110511548118027\\ -19 0.0810816442047581\\ -20 0.0724869690834777\\ -21 0.0664040226552164\\ -22 0.0584625428431533\\ -23 0.0322850723515378\\ -24 0.0174209723963343\\ -25 0.0144234275217124\\ -26 0.0121558223280978\\ -27 0.0104094537953738\\ -28 0.0090009688542864\\ -29 0.00785779024825589\\ -30 0.00695804062242811\\ -31 0.00612739565717143\\ -32 0.00542141688862343\\ -33 0.00476127638738892\\ -34 0.00410460848216301\\ -35 0.0034833610562248\\ -36 0.00294163607888349\\ -37 0.00248498970375283\\ -38 0.00212522875726207\\ -39 0.00179637391524782\\ -40 0.00153523469540124\\ -}; -\addlegendentry{MLSE 3Lw: 0.5 MHz} - -\addplot [color=white!15!black, dashed, forget plot] - table[row sep=crcr]{% -15 0.0038\\ -40 0.0038\\ -}; -\addplot [color=white!15!black, dashed, forget plot] - table[row sep=crcr]{% -15 0.0038\\ -40 0.0038\\ -}; -\addplot [color=white!15!black, dashed, forget plot] - table[row sep=crcr]{% -15 0.0038\\ -40 0.0038\\ -}; -\end{axis} - -\begin{axis}[% -width=1.227\fwidth, -height=1.227\fheight, -at={(-0.16\fwidth,-0.135\fheight)}, -scale only axis, -xmin=0, -xmax=1, -ymin=0, -ymax=1, -axis line style={draw=none}, -ticks=none, -axis x line*=bottom, -axis y line*=left, -xmajorgrids, -ymajorgrids -] -\end{axis} -\end{tikzpicture}% \ No newline at end of file diff --git a/projects/A_minimal_example/imdd_simulation_minimal.m b/projects/A_minimal_example/imdd_simulation_minimal.m new file mode 100644 index 0000000..bb81c3f --- /dev/null +++ b/projects/A_minimal_example/imdd_simulation_minimal.m @@ -0,0 +1,175 @@ +function [ber] = imdd_simulation_minimal(varargin) +% BASIC IMDD Model... + +% varargin is either empty or a struct, i.e.: +% optionalvars = struct('bitrate',300e9,'M',6); +% then: +% imdd_simulation_minimal(optionalvars) +% replaces the respective variables -> nice for looping parameter sets + + curFolder = pwd; + funcFolder=fileparts(mfilename('fullpath')); + if ~isempty(funcFolder) + cd(funcFolder); + end + + % TX + M = 4; + fsym = 112e9; + apply_pulsef = 1; + fdac = 256e9; + fadc = 256e9; + random_key = 1; + db_precode = 0; + db_encode = 0; + rcalpha = 0.05; + kover = 16; + vbias_rel = 0.5; + u_pi = 2.9; + vbias = -vbias_rel*u_pi; + + laser_wavelength = 1310; + laser_linewidth = 0; + tx_bw_nyquist = 0.95; + + % Channel + link_length = 1; %km + + % RX + rop = -7; + rx_bw_nyquist = 0.9; + + % EQ + vnle_order=[50,7,7]; + dfe_order = [2 0 0]; + + len_tr = 4096*2; + mu_ffe = [0.0004 0.0004 0.0004]; + mu_dfe = 0.0004; + mu_dc = 0.00; + + % Replace optional input arguments if there are any + if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + end + else + error('Optional variables should be passed as a struct.'); + end + end + + fsym_ = floor( bitrate*1e-9./log2(M) ).*1e9; + if fsym_ ~= fsym + fsym = fsym_; + fprintf('Adapted symbolrate to %d GBd, to match provided bitrate of %d GBit/s using PAM %d \n',fsym.*1e-9,bitrate.*1e-9, M); + end + f_nyquist = fsym/2; + + %%%% TX Signal + Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha); + + [Digi_sig,Tx_symbols,Tx_bits] = PAMsource(... + "fsym",fsym,"M",M,"order",18,"useprbs",1,... + "fs_out",fdac,... + "applyclipping",0,"clipfactor",1.5,... + "applypulseform",apply_pulsef,"pulseformer",Pform,... + "randkey",random_key,... + "db_precode",db_precode,"db_encode",db_encode,... + "mrds_code",0,"mrds_blocklength",512).process(); + + Digi_sig.spectrum("displayname",'Digital Spectrum at TX','fignum',10,'normalizeTo0dB',1); + + %%%%% AWG + % El_sig = M8199A("kover",kover).process(Digi_sig); + El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",1,"kover",kover,"bit_resolution",12).process(Digi_sig); + % El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0); + El_sig = El_sig.setPower(0,"dBm"); + + El_sig.eye(fsym,M,"fignum",11,'displayname','Rx Eye'); + + %%%%% Low-pass el. components %%%%%% + El_sig = Filter('filtdegree',4,"f_cutoff",75e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig); + + %%%%% Electrical Driver Amplifier %%%%%% + El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig); + + %%%%% MODULATE E/O CONVERSION %%%%%% + [Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1).process(El_sig); + + %%%%%% Fiber %%%%%% + Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig); + + %%%%%% ROP %%%%%% + Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig); + + %%%%%% PD Square Law %%%%%% + Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig); + + Rx_sig.eye(fsym,M,"fignum",30,'displayname','Rx Eye'); + + %%%%%% Low-pass RX (PD, El. Connectors and Scope %%%%%% + Rx_sig = Filter('filtdegree',4,"f_cutoff",75e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(Rx_sig); + + %%%%%% Low-pass inside Scope %%%%%% + Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true); + + %%%%%% Scope %%%%%% + Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,... + "delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,... + "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... + "adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig); + + Scpe_sig.spectrum("displayname",'Digital (256 GSa/s) Rx Spectrum','fignum',10,'normalizeTo0dB',1); + + Scpe_sig.normalize("mode","rms").plot("displayname",'Digital (256 GSa/s) Rx Spectrum','fignum',21,'clear',1); + + %%%%%% Sample to 2x fsym %%%%%% + Scpe_sig = Scpe_sig.resample("fs_in",fadc,"fs_out",2*fsym); + + %%%%%% Sync Rx signal with reference %%%%%% + [Scpe_sig,S] = Scpe_sig.tsynch("reference",Tx_symbols,"fs_ref",fsym); + + + %%% EQUALIZING + + %FFE or VNLE + [Eq_signal,Eq_noise] = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1).process(Scpe_sig,Tx_symbols); + + Rx_bits = PAMmapper(M,0).demap(Eq_signal); + + [~,numErrors,ber,~] = calc_ber(Rx_bits.signal,Tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1); + + Eq_signal.normalize("mode","rms").plot("displayname",'Digital (256 GSa/s) Rx Spectrum','fignum',21,'clear',0); + + %%% Visualize EQ Stuff + + figure(40); + clf + title(sprintf('PAM %d after EQ ; BER: %1.2e',M, ber )); + constellation = unique(Tx_symbols.signal); + received = NaN(numel(constellation),length(Tx_symbols)); + for lvl = 1:numel(constellation) + %Separate the equalized signal into the + %respective levels based on the actually + %transmitted level! + received(lvl,Tx_symbols.signal==constellation(lvl)) = Eq_signal.signal(Tx_symbols.signal==constellation(lvl)); + intermediate = received(lvl,:); + cnt(lvl) = numel(intermediate(~isnan(intermediate))); + hold on + histogram(received(lvl,:),1000,"EdgeAlpha",0,'DisplayName',['Lvl ',num2str(lvl),' | ',num2str(cnt(lvl)),' entries']); + end + legend + + fprintf('BER: %.2e \n',ber); + + autoArrangeFigures; + + if ~isempty(curFolder) + cd(curFolder); + end + +end \ No newline at end of file diff --git a/projects/A_minimal_example/run_loops.m b/projects/A_minimal_example/run_loops.m new file mode 100644 index 0000000..23245d1 --- /dev/null +++ b/projects/A_minimal_example/run_loops.m @@ -0,0 +1,23 @@ +uloops = struct; +uloops.bitrate = [300,330,360,390,420,450,480].*1e9; +uloops.M = [4,6,8]; + +wh = DataStorage(uloops); +wh.addStorage("ber"); + +fprintf("Let's simulate %d configuratiuons! \n",wh.getLastLinIndice); + +wh = submit_simulations(wh,"parallel",1); + +for m_ = uloops.M + ber_row = wh.getStoValue('ber', uloops.bitrate,m_); + + figure(2024) + hold on + plot(uloops.bitrate.*1e-9,ber_row,'DisplayName',sprintf('PAM %d',m_)); +end + +yline(3.8e-3,'LineWidth',2,'DisplayName','3.8e-3'); +yline(2e-2,'LineWidth',2,'LineStyle','--','DisplayName','2e-2'); +beautifyBERplot() +legend \ No newline at end of file diff --git a/projects/A_minimal_example/submit_simulations.m b/projects/A_minimal_example/submit_simulations.m new file mode 100644 index 0000000..32509c5 --- /dev/null +++ b/projects/A_minimal_example/submit_simulations.m @@ -0,0 +1,72 @@ +function wh = submit_simulations(wh,options) + +arguments + wh + options.parallel = 1; +end + +%%% 2) SUBMIT SIMULATION +% Initialize job results +if options.parallel + if isempty(gcp('nocreate')) + parpool; + end + results = parallel.FevalFuture.empty(); +else + results = []; +end + + +lin_idx = 1; +for lin_idx = 1:wh.getLastLinIndice + optionalVars = struct(); + if ~isempty(wh.getDimension) + % Build the optionalVars struct + [parametervalues,parameternames]=wh.getPhysIndicesByLinIndex(lin_idx); + for pidx = 1:numel(parameternames) + optionalVars.(parameternames{pidx}) = parametervalues{pidx}; + end + end + + %%% SIMULATION HERE + if options.parallel + + numOutputs = 1; + results(lin_idx) = parfeval(@imdd_simulation_minimal, numOutputs, optionalVars); + + else + + finalresults{lin_idx} = imdd_simulation_minimal(optionalVars); + wh.addValueToStorageByLinIdx(finalresults{lin_idx}, 'ber', lin_idx); + + end +end + + + +if options.parallel + + %%% 4) Setup waitbar + h = waitbar(0, 'Processing Simulations...'); + % Helper function to compute progress + updateWaitbar = @(~) waitbar(mean(arrayfun(@(f) strcmp(f.State, 'finished'), results)), h); + + fprintf('Fetching results... \n'); + + % Update the waitbar after each simulation + updateWaitbarFutures = afterEach(results, updateWaitbar, 0); + + % Close the waitbar after all simulations complete + afterAll(updateWaitbarFutures, @(~) delete(h), 0); + + %%% 7) Fetch final results after all computations + fetchOutputs(results); + + for ridx = 1:length(results) + wh.addValueToStorageByLinIdx(results(ridx).OutputArguments{1}, 'ber', ridx); + end + +end + + +end \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/App/Block_Diagram.svg b/projects/HighSpeedExperiment_2024/auswertung/App/Block_Diagram.svg new file mode 100644 index 0000000..202800c --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/App/Block_Diagram.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AWG + + + + + + + + + + + + + + + + + + + + + + P + + + launch + + + + + + + + + + + + + + PD + + + in + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/HighSpeedExperiment_2024/auswertung/App/auswertungs_app.mlapp b/projects/HighSpeedExperiment_2024/auswertung/App/auswertungs_app.mlapp new file mode 100644 index 0000000..375605d Binary files /dev/null and b/projects/HighSpeedExperiment_2024/auswertung/App/auswertungs_app.mlapp differ diff --git a/projects/HighSpeedExperiment_2024/auswertung/App/database_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/projects/HighSpeedExperiment_2024/auswertung/App/database_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..e1dfb1c --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/App/database_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/App/query_stats_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/projects/HighSpeedExperiment_2024/auswertung/App/query_stats_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..93430ca --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/App/query_stats_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/App/table_convert_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg b/projects/HighSpeedExperiment_2024/auswertung/App/table_convert_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg new file mode 100644 index 0000000..a94012f --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/App/table_convert_24dp_E8EAED_FILL0_wght400_GRAD0_opsz24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/analyzeDB.m b/projects/HighSpeedExperiment_2024/auswertung/analyzeDB.m deleted file mode 100644 index 0183686..0000000 --- a/projects/HighSpeedExperiment_2024/auswertung/analyzeDB.m +++ /dev/null @@ -1,85 +0,0 @@ -basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; -useGui = 0; - -db = DBHandler("pathToDB",[basePath,'silas_labor.db']); -if useGui - filterParams = db.promptFilterParameters(); - selectedFields = db.promptSelectFields(); -else - filterParams = db.tables; - filterParams.Configurations = struct( ... - 'bitrate', [], ... - 'db_mode', [], ... - 'fiber_length', 10, ... - 'interference_attenuation', [], ... - 'interference_path_length', [], ... - 'is_mpi', 0, ... - 'pam_level', [], ... - 'precomp_amp', [], ... - 'rop_attenuation', 0, ... - 'symbolrate', [], ... - 'v_awg', [], ... - 'v_bias', [], ... - 'wavelength', 1310 ... - ); - filterParams.Equalizer.eq_type = equalizer_structure.vnle_pf_mlse; - filterParams.Equalizer.eq_id = equalizer_structure.vnle; - selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','Equalizer.eq_type','BERs.ber','BERs.occurrence',... - 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp',... - 'Measurements.power_rop','Measurements.power_laser','Measurements.power_pd_in'}; -end - - -[dataTable,~] = db.queryDB(filterParams, selectedFields); - -% Calculate the mean BER for each combination of 'run_id' and 'eq_type' -groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, 'mean', {'ber', 'power_rop','power_pd_in'}); - -% Extract unique rows from dataTable for each run_id with relevant configuration details -uniqueConfigFields = {'run_id', 'pam_level', 'bitrate','symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'}; -[~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices -configDetails = dataTable(uniqueIdx, uniqueConfigFields); % Extract unique configurations for each run_id - -% Prepare the join key for both groupedData and configDetails -groupedDataTable = table(groupedData.run_id, groupedData.eq_type, groupedData.GroupCount, groupedData.mean_ber,groupedData.mean_power_rop,groupedData.mean_power_pd_in, ... - 'VariableNames', {'run_id', 'eq_type', 'GroupCount', 'mean_ber','mean_power_rop','mean_power_pd_in'}); - -% Join groupedData with configDetails on the run_id field -joinedData = join(groupedDataTable, configDetails, 'Keys', 'run_id'); - - - - -a=plot(fsym_vals.*1e-9.*log2(M_vals(modulation_iter)),ber_ffe(:,modulation_iter),... - 'Color',cols(modulation_iter,:),'MarkerSize',2,'LineWidth',1,... - 'Marker','o','MarkerFaceColor',cols(modulation_iter,:),'MarkerEdgeColor','black',... - 'DisplayName',['PAM ',num2str(M_vals(modulation_iter))]); - -a.DataTipTemplate.DataTipRows(1).Label = 'Bitr'; -a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',' Gbps']; - -a.DataTipTemplate.DataTipRows(2).Label = 'BER'; -a.DataTipTemplate.DataTipRows(2).Format ='%.1e'; - -a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}'; -a.DataTipTemplate.DataTipRows(3).Value = rop(:,modulation_iter); -a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm']; - -a.DataTipTemplate.DataTipRows(4).Label = 'Baudr'; -a.DataTipTemplate.DataTipRows(4).Value = fsym_vals.*1e-9; -a.DataTipTemplate.DataTipRows(4).Format = ['%.1f',' GBd']; - - -a.DataTipTemplate.FontSize = 9; -a.DataTipTemplate.FontName = 'arial'; - -% Continue with the rest of your plot settings -title('Opt B2B') -yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off'); -xlabel('Bit Rate in GBps'); -ylabel('Bit Error Rate (BER)'); -set(gca, 'yscale', 'log'); -set(gca, 'Box', 'on'); -grid on; -grid minor; -legend('Interpreter', 'none'); diff --git a/projects/HighSpeedExperiment_2024/auswertung/analyzeDB_shortened.m b/projects/HighSpeedExperiment_2024/auswertung/analyzeDB_shortened.m new file mode 100644 index 0000000..3480251 --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/analyzeDB_shortened.m @@ -0,0 +1,137 @@ +basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; +useGui = 0; +pamlvls = [4, 6, 8]; +wlengths = [1310]; +db = DBHandler("pathToDB", [basePath, 'silas_labor.db']); + +for w = 1:numel(wlengths) + for p = 1:numel(pamlvls) + % Load data from database + joinedData = loadDataFromDB(db, pamlvls(p), wlengths(w), useGui); + + % Plot filtered data + figure(pamlvls(p)); + hold on; + plotFilteredData(joinedData, wlengths(w)); + % Continue with the rest of your plot settings + finalizePlot(); + end +end + + +% Custom function to load data from database +function joinedData = loadDataFromDB(db, pamlvl, wlength, useGui) + if useGui + filterParams = db.promptFilterParameters(); + selectedFields = db.promptSelectFields(); + else + filterParams = db.tables; + filterParams.Configurations = struct( ... + 'bitrate', [], 'db_mode', [], 'fiber_length', 1, ... + 'interference_attenuation', [], 'interference_path_length', [], ... + 'is_mpi', 0, 'pam_level', pamlvl, 'precomp_amp', [], ... + 'rop_attenuation', 0, 'symbolrate', [], 'v_awg', [], 'v_bias', [], ... + 'wavelength', wlength ... + ); + + selectedFields = {'Runs.run_id', 'BERs.ber_id', 'Equalizer.eq_id', 'Equalizer.eq_type', 'BERs.ber', 'BERs.occurrence', ... + 'Configurations.db_mode', 'Configurations.pam_level', 'Configurations.bitrate', 'Configurations.symbolrate', ... + 'Configurations.fiber_length', 'Configurations.wavelength', 'Configurations.precomp_amp', ... + 'Measurements.power_rop', 'Measurements.power_laser', 'Measurements.power_pd_in'}; + end + + % Get data table from DB + [dataTable, ~] = db.queryDB(filterParams, selectedFields); + + % Extract unique rows for each run_id + uniqueConfigFields = {'run_id', 'pam_level', 'bitrate', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'}; + [~, uniqueIdx] = unique(dataTable.run_id); + configDetails = dataTable(uniqueIdx, uniqueConfigFields); + + % Calculate the mean BER for each combination of 'run_id' and 'eq_type' + groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop', 'power_pd_in'}); + + % Join groupedData with configDetails on the run_id field + joinedData = join(groupedData, configDetails, 'Keys', 'run_id'); +end + +% Custom function to plot filtered data +function plotFilteredData(joinedData, wlength) + filterFields = {'eq_type'}; + cols = linspecer(8); + lst = ["-", ":", "--"]; + + % Loop over each field you want to filter by + for f = 1:numel(filterFields) + currentField = filterFields{f}; + uniqueValues = unique(joinedData.(currentField)); + + for i = 1:numel(uniqueValues) + currentValue = uniqueValues(i); + + % Filter joinedData for the current value + if isnumeric(currentValue) + filteredData = joinedData(joinedData.(currentField) == currentValue, :); + else + filteredData = joinedData(strcmp(joinedData.(currentField), currentValue), :); + end + + % Group and average BERs of several run ids => repeated measurements in lab! + groupVars = {'bitrate'}; + groupedDataWithMeans = groupsummary(filteredData, groupVars, {'mean', 'min'}, {'mean_ber', 'min_ber', 'fun1_ber', 'mean_power_rop', 'mean_power_pd_in'}); + [~, uniqueIdx] = unique(filteredData.bitrate); + constantFields = filteredData(uniqueIdx, {'bitrate', 'GroupCount', 'pam_level', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'}); + groupedRunIDs = varfun(@(x) {unique(x)}, filteredData, 'GroupingVariables', groupVars, 'InputVariables', 'run_id'); + groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'}; + groupedDataWithMeans = join(groupedDataWithMeans, constantFields, 'Keys', 'bitrate'); + groupedDataWithMeans = join(groupedDataWithMeans, groupedRunIDs, 'Keys', 'bitrate'); + filteredData = groupedDataWithMeans; + + % Plotting + a = plot(filteredData.bitrate .* 1e-9, filteredData.mean_fun1_ber, ... + 'Color', cols(i, :), 'MarkerSize', 4, 'LineWidth', 1, 'LineStyle', lst(mod(wlength - 1, numel(lst)) + 1), ... + 'Marker', 'o', 'MarkerFaceColor', 'auto', 'MarkerEdgeColor', cols(i, :), ... + 'DisplayName', [char(currentValue), '; ', num2str(wlength), ' nm']); + + a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate'; + a.DataTipTemplate.DataTipRows(1).Format = ['%.1f', ' Gbit/s']; + a.DataTipTemplate.DataTipRows(2).Label = 'BER'; + a.DataTipTemplate.DataTipRows(2).Format = '%.1e'; + a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}'; + a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_mean_power_rop; + a.DataTipTemplate.DataTipRows(3).Format = ['%.2f', ' dBm']; + a.DataTipTemplate.DataTipRows(4).Label = 'Baudr'; + a.DataTipTemplate.DataTipRows(4).Value = filteredData.bitrate .* 1e-9; + a.DataTipTemplate.DataTipRows(4).Format = ['%.1f', ' GBd']; + a.DataTipTemplate.DataTipRows(5).Label = 'Run ID'; + a.DataTipTemplate.DataTipRows(5).Value = filteredData.GroupedRunIDs; + a.DataTipTemplate.FontSize = 9; + a.DataTipTemplate.FontName = 'arial'; + end + end +end + +% Custom function to finalize the plot settings +function finalizePlot() + yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off'); + yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off'); + xlabel('Bit Rate in GBps'); + ylabel('Bit Error Rate (BER)'); + xlim([300, 480]); + set(gca, 'yscale', 'log'); + set(gca, 'Box', 'on'); + grid on; + grid minor; + legend('Interpreter', 'none'); +end + +% Custom function using rmoutliers to calculate mean after removing outliers +function meanWithoutOutliers = meanExcludingOutliers(x) + [xWithoutOutliers,outlierpos] = rmoutliers(x); + if isempty(xWithoutOutliers) + meanWithoutOutliers = NaN; + else + meanWithoutOutliers = mean(xWithoutOutliers); + end + +end diff --git a/projects/HighSpeedExperiment_2024/auswertung/auswertungs_app.mlapp b/projects/HighSpeedExperiment_2024/auswertung/auswertungs_app.mlapp deleted file mode 100644 index c7cc12d..0000000 Binary files a/projects/HighSpeedExperiment_2024/auswertung/auswertungs_app.mlapp and /dev/null differ diff --git a/projects/HighSpeedExperiment_2024/auswertung/ber_vs_bitrate.m b/projects/HighSpeedExperiment_2024/auswertung/ber_vs_bitrate.m new file mode 100644 index 0000000..ce23d75 --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/ber_vs_bitrate.m @@ -0,0 +1,170 @@ +basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; +useGui = 0; +pamlvls = [4,6,8]; +wlengths = [1302]; +figoffset = 0; + +figure(30) +tiledlayout(1, 3, 'TileSpacing', 'compact', 'Padding', 'compact'); + +for p = 1:numel(pamlvls) + nexttile; + + for w = 1:numel(wlengths) + sgtitle(['Lambda: ',num2str(wlengths),' nm']) + + hold on + pamlvl = pamlvls(p); + wlength = wlengths(w); + db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + if useGui + filterParams = db.promptFilterParameters(); + selectedFields = db.promptSelectFields(); + else + filterParams = db.tables; + filterParams.Configurations = struct( ... + 'bitrate', [], ... + 'db_mode', [], ... + 'fiber_length', 10, ... + 'interference_attenuation', [], ... + 'interference_path_length', [], ... + 'is_mpi', 0, ... + 'pam_level', pamlvl, ... + 'precomp_amp', [], ... + 'rop_attenuation', 0, ... + 'symbolrate', [], ... + 'v_awg', [], ... + 'v_bias', [], ... + 'wavelength', wlength ... + ); + + selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','Equalizer.eq_type','BERs.ber','BERs.occurrence',... + 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp',... + 'Measurements.power_rop','Measurements.power_laser','Measurements.power_pd_in'}; + end + + % Get data table from DB + [dataTable,~] = db.queryDB(filterParams, selectedFields); + + % Grouping variables: 'bitrate' and 'eq_type' + groupVars = {'bitrate', 'eq_type'}; + + % Calculate mean BER for each combination of 'bitrate' and 'eq_type' + groupedData = groupsummary(dataTable, groupVars, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop','power_pd_in'}); + + % Collect the run_id values for each group + groupedRunIDs = varfun(@(x) {unique(x)}, dataTable, 'GroupingVariables', groupVars, 'InputVariables', 'run_id'); + groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'}; + + % Join the grouped data with the grouped run_id list + avgdBerTable = join(groupedData, groupedRunIDs, 'Keys', groupVars); + + % Define the fields that you want to use for filtering + filterFields = {'eq_type'}; + + % Loop over each field you want to filter by + for f = 1:numel(filterFields) + currentField = filterFields{f}; + + % Determine unique values for the current field + uniqueValues = unique(avgdBerTable.(currentField)); + + % Loop over each unique value for the current field + for i = 1:numel(uniqueValues) + currentValue = uniqueValues(i); + + % Filter joinedData for the current value + if isnumeric(currentValue) + filteredData = avgdBerTable(avgdBerTable.(currentField) == currentValue, :); + else + filteredData = avgdBerTable(strcmp(avgdBerTable.(currentField), currentValue), :); + end + + cols = linspecer(8); + + lst = ["-",":","--"]; + a=plot(filteredData.bitrate.*1e-9,filteredData.min_ber,... + 'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',lst(w),... + 'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),... + 'DisplayName',[char(currentValue),'; ',num2str(wlength),' nm' ]); + a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate'; + a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',' Gbit/s']; + + a.DataTipTemplate.DataTipRows(2).Label = 'BER'; + a.DataTipTemplate.DataTipRows(2).Format ='%.1e'; + + a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}'; + a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_power_rop; + a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm']; + + a.DataTipTemplate.DataTipRows(4).Label = 'Run ID'; + a.DataTipTemplate.DataTipRows(4).Value = filteredData.GroupedRunIDs; + a.DataTipTemplate.DataTipRows(4).Format = ['%d',' ']; + + + a.DataTipTemplate.FontSize = 9; + a.DataTipTemplate.FontName = 'arial'; + % + % a=scatter(filteredData.bitrate.*1e-9,filteredData.min_ber,5,'Marker','diamond',... + % 'Color',cols(i,:),'LineWidth',1,... + % 'MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),... + % 'DisplayName',currentValue); + % + % a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate'; + % a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',' Gbit/s']; + % + % a.DataTipTemplate.DataTipRows(2).Label = 'BER'; + % a.DataTipTemplate.DataTipRows(2).Format ='%.1e'; + % + % a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}'; + % a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_power_rop; + % a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm']; + % + % a.DataTipTemplate.DataTipRows(4).Label = 'Run ID'; + % a.DataTipTemplate.DataTipRows(4).Value = filteredData.GroupedRunIDs; + % a.DataTipTemplate.DataTipRows(4).Format = ['%d',' ']; + % + % + % a.DataTipTemplate.FontSize = 9; + % a.DataTipTemplate.FontName = 'arial'; + + + + + end + end + + + + % Continue with the rest of your plot settings + title(sprintf('%d km | %d nm | PAM %d',unique(filterParams.Configurations.fiber_length),wlength,pamlvl)); + yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off','LineWidth',1); + yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off','LineWidth',1); + xlabel('Bit Rate in Gbps'); + ylabel('Bit Error Rate'); + xlim([300, 480]) + ylim([8e-4,0.5]) + set(gca, 'yscale', 'log'); + set(gca, 'Box', 'on'); + grid on; + grid minor; + + + end +end +legend('Interpreter', 'none'); +set(gcf, 'Units', 'pixels', 'Position', 1.0e+03 * [0.2483 0.7303 1.2093 0.3980]); + +% Custom function using rmoutliers to calculate mean after removing outliers +function meanWithoutOutliers = meanExcludingOutliers(x) +% Remove outliers using rmoutliers with default method (based on median) +xWithoutOutliers = rmoutliers(x); + +% Calculate the mean of the non-outliers +if isempty(xWithoutOutliers) + % Handle the case where all values are outliers + meanWithoutOutliers = NaN; +else + meanWithoutOutliers = mean(xWithoutOutliers); +end +end \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/ber_vs_length.m b/projects/HighSpeedExperiment_2024/auswertung/ber_vs_length.m new file mode 100644 index 0000000..bd7032b --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/ber_vs_length.m @@ -0,0 +1,192 @@ +basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; +useGui = 0; +pamlvls = [6]; +wlengths = [1293,1302,1310];%db.distinctValues.Configurations.wavelength +figoffset = 20; + +figure(21) +tiledlayout(1, 3, 'TileSpacing', 'compact', 'Padding', 'compact'); + + +for w = 1:numel(wlengths) + nexttile; + for p = 1:numel(pamlvls) + pamlvl = pamlvls(p); + wlength = wlengths(w); + db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + if useGui + filterParams = db.promptFilterParameters(); + selectedFields = db.promptSelectFields(); + else + filterParams = db.tables; + filterParams.Configurations = struct( ... + 'bitrate', 420e9, ... + 'db_mode', [], ... + 'fiber_length', [], ... + 'interference_attenuation', [], ... + 'interference_path_length', [], ... + 'is_mpi', 0, ... + 'pam_level', pamlvl, ... + 'precomp_amp', [], ... + 'rop_attenuation', 0, ... + 'symbolrate', [], ... + 'v_awg', [], ... + 'v_bias', [], ... + 'wavelength', wlength ... + ); + % filterParams.Equalizer.eq_type = equalizer_structure.vnle; + + selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','Equalizer.eq_type','BERs.ber','BERs.occurrence',... + 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp',... + 'Measurements.power_rop','Measurements.power_laser','Measurements.power_pd_in'}; + end + sgtitle(['Rate: ',num2str(filterParams.Configurations.bitrate),' Gbit/s']) + % Get data table from DB + [dataTable,~] = db.queryDB(filterParams, selectedFields); + + % Extract unique rows from dataTable for each run_id with relevant configuration details + uniqueConfigFields = {'run_id', 'pam_level', 'bitrate','symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'}; + [~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices + configDetails = dataTable(uniqueIdx, uniqueConfigFields); % Extract unique configurations for each run_id + + % Calculate the mean BER for each combination of 'run_id' and 'eq_type' + groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean','min'}, {'ber', 'power_rop','power_pd_in'}); + groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop','power_pd_in'}); + + % Join groupedData with configDetails on the run_id field + joinedData = join(groupedData, configDetails, 'Keys', 'run_id'); + + + % Define the fields that you want to use for filtering + filterFields = {'eq_type'}; + + % Create a cell array to store filtered data tables for each filter field + filteredDataByField = struct(); + + hold on + % Loop over each field you want to filter by + for f = 1:numel(filterFields) + currentField = filterFields{f}; + + % Determine unique values for the current field + uniqueValues = unique(joinedData.(currentField)); + + % Create a struct entry for the current field + filteredDataByField.(currentField) = cell(numel(uniqueValues), 1); + + % Loop over each unique value for the current field + for i = 1:numel(uniqueValues) + currentValue = uniqueValues(i); + + % Filter joinedData for the current value + if isnumeric(currentValue) + filteredData = joinedData(joinedData.(currentField) == currentValue, :); + else + filteredData = joinedData(strcmp(joinedData.(currentField), currentValue), :); + end + + %%% workaround to average the BERs of several runs (ie in 1km case or trials) + %%% Workaround to average the BERs of several runs (e.g., in 1 km case or trials) + + % Grouping variable(s) + groupVars = {'fiber_length'}; + + % Use groupsummary to calculate the mean and min of relevant fields + groupedDataWithMeans = groupsummary(filteredData, groupVars, {'mean', 'min'}, {'mean_ber', 'min_ber', 'fun1_ber', 'mean_power_rop', 'mean_power_pd_in'}); + + % Extract representative values for constant fields + [~, uniqueIdx] = unique(filteredData.(groupVars{1})); % Get the first occurrence of each bitrate value + constantFields = filteredData(uniqueIdx, {'bitrate', 'GroupCount', 'pam_level', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'}); + + % Keep track of which run_id values were grouped + groupedRunIDs = varfun(@(x) {unique(x)}, filteredData, 'GroupingVariables', groupVars, 'InputVariables', 'run_id'); + groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'}; + + % Join the grouped data with the constant fields + groupedDataWithMeans = join(groupedDataWithMeans, constantFields, 'Keys', groupVars); + + % Join the grouped data with the grouped run_id list + groupedDataWithMeans = join(groupedDataWithMeans, groupedRunIDs, 'Keys', groupVars); + + % Update filteredData to include the grouped information + filteredData = groupedDataWithMeans; + %%% end of workaround + + + + cols = linspecer(8); + % a=plot(filteredData.bitrate.*1e-9,filteredData.mean_mean_ber,... + % 'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',':',... + % 'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),... + % 'DisplayName',currentValue); + + lst = ["-",":","--"]; + a=plot(filteredData.(groupVars{1}),filteredData.mean_fun1_ber,... + 'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',lst(1),... + 'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),... + 'DisplayName',[char(currentValue),'; ',num2str(wlength),' nm' ]); + % + % scatter(filteredData.symbolrate.*1e-9,filteredData.min_min_ber,5,'Marker','_',... + % 'Color',cols(i,:),'LineWidth',1,... + % 'MarkerFaceColor',cols(i,:),'MarkerEdgeColor','black',... + % 'DisplayName',currentValue); + + a.DataTipTemplate.DataTipRows(1).Label = groupVars{1}; + a.DataTipTemplate.DataTipRows(1).Format = ['%.1f','']; + + a.DataTipTemplate.DataTipRows(2).Label = 'BER'; + a.DataTipTemplate.DataTipRows(2).Format ='%.1e'; + + a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}'; + a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_mean_power_rop; + a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm']; + + a.DataTipTemplate.DataTipRows(4).Label = 'Baudr'; + a.DataTipTemplate.DataTipRows(4).Value = filteredData.bitrate .*1e-9; + a.DataTipTemplate.DataTipRows(4).Format = ['%.1f',' GBd']; + + a.DataTipTemplate.DataTipRows(5).Label = 'Run ID'; + a.DataTipTemplate.DataTipRows(5).Value = filteredData.GroupedRunIDs; + a.DataTipTemplate.DataTipRows(5).Format = ['%f',' GBd']; + + + a.DataTipTemplate.FontSize = 9; + a.DataTipTemplate.FontName = 'arial'; + + end + end + + + + % Continue with the rest of your plot settings + title(sprintf('Lambda: %f',wlength)); + yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off'); + yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off'); + xlabel(groupVars{1},'Interpreter','none'); + ylabel('Bit Error Rate (BER)'); + %xlim([300, 480]) + ylim([8e-4,0.5]) + set(gca, 'yscale', 'log'); + set(gca, 'Box', 'on'); + grid on; + grid minor; + legend('Interpreter', 'none'); + + + + end +end + +% Custom function using rmoutliers to calculate mean after removing outliers +function meanWithoutOutliers = meanExcludingOutliers(x) +% Remove outliers using rmoutliers with default method (based on median) +xWithoutOutliers = rmoutliers(x); + +% Calculate the mean of the non-outliers +if isempty(xWithoutOutliers) + % Handle the case where all values are outliers + meanWithoutOutliers = NaN; +else + meanWithoutOutliers = mean(xWithoutOutliers); +end +end \ No newline at end of file diff --git a/projects/HighSpeedExperiment_2024/auswertung/buildDBfromMeasurements.m b/projects/HighSpeedExperiment_2024/auswertung/buildDBfromMeasurements.m index 56f3612..152a37a 100644 --- a/projects/HighSpeedExperiment_2024/auswertung/buildDBfromMeasurements.m +++ b/projects/HighSpeedExperiment_2024/auswertung/buildDBfromMeasurements.m @@ -17,18 +17,56 @@ folderNames = folderNames(~ismember(folderNames, {'.', '..'})); % Combine folder names with paths fullFolderPaths = flip(fullfile(folderPaths, folderNames)); -only_mpi=0; +% process only MPI? +only_mpi=0; if only_mpi fullFolderPaths = fullFolderPaths(contains(fullFolderPaths,"mpi")); end -relativeFolderPaths = strrep(fullFolderPaths, sioe_labor_path, ''); +% Shorten folder paths to display only the folder name after the last filesep +displayFolderPaths = cellfun(@(x) x(find(x == filesep, 1, 'last') + 1 : end), fullFolderPaths, 'UniformOutput', false); + +% Create checkbox settings for each folder path +numFolders = numel(fullFolderPaths); +checkboxSettings = cell(1, 2 * numFolders); +for i = 1:numFolders + checkboxSettings{2*i-1} = {displayFolderPaths{i}; sprintf('Folder_%d', i)}; + checkboxSettings{2*i} = true; % Set false for unchecked by default +end + +% Create settings dialog using settingsdlg +[settings, button] = settingsdlg( ... + 'Description', 'Select Folders to Process:', ... + 'title', 'Folder Selection', ... + checkboxSettings{:}); + +% Check if the user pressed OK +if strcmp(button, 'OK') + % Get all the field names from settings + allFields = fieldnames(settings); + + % Determine which folders were selected + selectedFoldersIdx = cellfun(@(x) settings.(x), allFields); + + % Get the list of selected folders + selectedFolders = fullFolderPaths(selectedFoldersIdx==1); + + % Display the selected folders + fprintf('Selected Folders to Process:\n'); + disp(selectedFolders); +else + fprintf('No folders selected.\n'); +end + + +relativeFolderPaths = strrep(selectedFolders, sioe_labor_path, ''); disp(['Start to process ',num2str(numel(relativeFolderPaths)), ' folder in the directory']); -for f = 1:numel(fullFolderPaths) - folder = fullFolderPaths{f}; + +for f = 1:numel(selectedFolders) + folder = selectedFolders{n}; relfolder = relativeFolderPaths{f}; @@ -106,18 +144,18 @@ for f = 1:numel(fullFolderPaths) params_merge = struct; for c = 1:numel(big_wh_list) fnames = fieldnames(big_wh_list{c}.parameter); - for f = 1:numel(fnames) + for fn = 1:numel(fnames) % Initialize field if not already present - if ~isfield(params_merge, fnames{f}) - params_merge.(fnames{f}) = []; + if ~isfield(params_merge, fnames{fn}) + params_merge.(fnames{fn}) = []; end % Merge unique parameter values into params_merge - a = big_wh_list{c}.parameter.(fnames{f}).values; - b = params_merge.(fnames{f}); + a = big_wh_list{c}.parameter.(fnames{fn}).values; + b = params_merge.(fnames{fn}); vals_to_add = setdiff(a, b); % New values in a that aren't in b b = sort([b, vals_to_add]); % Combine and sort values - params_merge.(fnames{f}) = b; + params_merge.(fnames{fn}) = b; end end @@ -157,11 +195,11 @@ for f = 1:numel(fullFolderPaths) isMPI = isfield(measurementStruct,'i_power'); - % Process record if it contains data + % Process record if it contains *any* data if recordIsFilled if ~isMPI - + % Generate filenames with conditionally formatted parameters % Format the L parameter value (show decimal only if non-zero) if configStruct.lambda == floor(configStruct.lambda) @@ -175,8 +213,13 @@ for f = 1:numel(fullFolderPaths) configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, 0); fbody_tx = strrep(fbody_tx, '.', '_'); % Replace decimal point with underscore - fbody_rx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%d', datebody, ... - configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, configStruct.rop_atten); + if configStruct.rop_atten == round(configStruct.rop_atten) + fbody_rx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%d', datebody, ... + configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, configStruct.rop_atten); + else + fbody_rx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%.1f', datebody, ... + configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, configStruct.rop_atten); + end fbody_rx = strrep(fbody_rx, '.', '_'); elseif isMPI @@ -185,8 +228,13 @@ for f = 1:numel(fullFolderPaths) configStruct.M, configStruct.bitrate, configStruct.duobinary, 0); fbody_tx = strrep(fbody_tx, '.', '_'); % Replace decimal point with underscore - fbody_rx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%d', datebody, ... - configStruct.M, configStruct.bitrate, configStruct.duobinary, configStruct.interference_atten); + if configStruct.interference_atten == round(configStruct.interference_atten) + fbody_rx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%d', datebody, ... + configStruct.M, configStruct.bitrate, configStruct.duobinary, configStruct.interference_atten); + else + fbody_rx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%.1f', datebody, ... + configStruct.M, configStruct.bitrate, configStruct.duobinary, configStruct.interference_atten); + end fbody_rx = strrep(fbody_rx, '.', '_'); % Replace decimal point with underscore end @@ -223,6 +271,7 @@ for f = 1:numel(fullFolderPaths) % SYNCHRONIZED RX SIGNAL fn_rxtsynch = [filesep, fbody_rx, '_rx_signal.mat']; fp_rxtsynch = fullfile([folder, fn_rxtsynch]); + fn_rxtsynch_rel = []; if exist(fp_rxtsynch, "file") == 2 fn_rxtsynch_rel = [relfolder, fn_rxtsynch]; @@ -244,13 +293,42 @@ for f = 1:numel(fullFolderPaths) end end end + + elseif exist(fp_rxtsynch, "file") == 0 + + disp(['RX Signal not found at: ', fn_rxtsynch,' generate and save new one using symbols and raw signal']); + + Scpe_sig_raw = load(fp_rxraw); + Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw; + + Symbols = load(fp_symbols); + Symbols = Symbols.Symbols; + %%%%%% Sample to 2x fsym %%%%%% + Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",Scpe_sig_raw.fs,"fs_out",2*Symbols.fs); + %%%%%% Sync Rx signal with reference (S is a cell array with all occurences) %%%%%% + [Scpe_sig_syncd,S,isFlipped] = Scpe_sig_resampled.tsynch("reference",Symbols,"fs_ref",Symbols.fs); + %%%%% Plot and Save Routines: SAVE RECEIVED SIGNALS %%%%%%%%%%%%%%%%%%%%%%%%% + save(fp_rxtsynch,"S"); + + if exist(fp_rxtsynch, "file") == 0 + warndlg('Something still wromg... No rx file here but we just generated it from raw signal'); + end + + fn_rxtsynch_rel = [relfolder, fn_rxtsynch]; + elseif missing_raw_flag - warning(['RX Signal not found at: ', fn_rxtsynch]); + warndlg('No RAW or RX signal found! This is bad!'); + % look at measurementStruct and configStruct end + else + disp('Record not filled?') + % look at measurementStruct and configStruct end % Call the duplicate check function - exists = db.checkIfRunExists('Runs', 'rx_sync_path', fn_rxtsynch_rel); + if ~isempty(fn_rxtsynch_rel) + exists = db.checkIfRunExists('Runs', 'rx_sync_path', fn_rxtsynch_rel); + end if ~exists @@ -335,31 +413,32 @@ for f = 1:numel(fullFolderPaths) % Append the new row to the Measurements table db.appendToTable('Measurements', newMeas); - % Table 4: Append to Bers - [ber, structure, settings] = getBers(configStruct,measurementStruct); - for t = 1:numel(ber) - - if iscell(ber(t)) - ber_ = ber(t); - ber_ = ber_{1}; - else - ber_ = ber(t); - end - - if ber_~=-1 - - newBer = struct(... - 'ber_id', NaN,... - 'run_id', run_id,... - 'processing_structure', structure(t),... - 'processing_settings', settings(t),... - 'ber', jsonencode(ber_)... - ); - db.appendToTable('BERs', newBer); - - end - - end + % % Table 4: Append to Bers + % [ber, structure, settings] = getBers(configStruct,measurementStruct); + % for t = 1:numel(ber) + % + % if iscell(ber(t)) + % ber_ = ber(t); + % ber_ = ber_{1}; + % else + % ber_ = ber(t); + % end + % + % if ber_~=-1 + % + % newBer = struct(... + % 'ber_id', NaN,... + % 'run_id', run_id,... + % 'processing_structure', structure(t),... + % 'processing_settings', settings(t),... + % 'ber', jsonencode(ber_)... + % ); + % + % db.appendToTable('BERs', newBer); + % + % end + % + % end end diff --git a/projects/HighSpeedExperiment_2024/auswertung/checkDBpaths.m b/projects/HighSpeedExperiment_2024/auswertung/checkDBpaths.m new file mode 100644 index 0000000..7d3ba3d --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/checkDBpaths.m @@ -0,0 +1,42 @@ +% Load the Runs table from the database +db = DBHandler("pathToDB", 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\silas_labor.db'); +runsTable = db.queryDB(db.tables, {'Runs.run_id', 'Runs.tx_bits_path', 'Runs.tx_symbols_path', 'Runs.rx_sync_path', 'Runs.rx_raw_path', 'Runs.filename'}); + +% Initialize an array to store the result of existence check +fileExistenceResults = false(height(runsTable), 4); % 4 columns for the paths: tx_bits, tx_symbols, rx_sync, rx_raw + +% Main file path +sioe_labor_path = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor'; + +% Loop through all rows in the table and check paths +for i = 1:height(runsTable) + fileExistenceResults(i, 1) = exist([sioe_labor_path, runsTable.tx_bits_path{i}], 'file') == 2; + fileExistenceResults(i, 2) = exist([sioe_labor_path, runsTable.tx_symbols_path{i}], 'file') == 2; + fileExistenceResults(i, 3) = exist([sioe_labor_path, runsTable.rx_sync_path{i}], 'file') == 2; + fileExistenceResults(i, 4) = exist([sioe_labor_path, runsTable.rx_raw_path{i}], 'file') == 2; +end + +% Identify corrupted run_ids (where any path does not exist) +corruptedRunIds = runsTable.run_id(~all(fileExistenceResults, 2)); + +% Delete entries in all tables related to corrupted run_ids +for i = 1:numel(corruptedRunIds) + run_id = corruptedRunIds(i); + + % Delete from BERs table + db.executeSQL(sprintf('DELETE FROM BERs WHERE run_id = %d;', run_id)); + + % Delete from Equalizer table (if applicable) + db.executeSQL(sprintf('DELETE FROM Equalizer WHERE eq_id IN (SELECT eq_id FROM BERs WHERE run_id = %d);', run_id)); + + % Delete from Measurements table + db.executeSQL(sprintf('DELETE FROM Measurements WHERE run_id = %d;', run_id)); + + % Delete from Configurations table + db.executeSQL(sprintf('DELETE FROM Configurations WHERE run_id = %d;', run_id)); + + % Delete from Runs table + db.executeSQL(sprintf('DELETE FROM Runs WHERE run_id = %d;', run_id)); +end +% +% disp('Entries for corrupted run_ids have been removed from the database.'); diff --git a/projects/HighSpeedExperiment_2024/auswertung/getBerForRunId.m b/projects/HighSpeedExperiment_2024/auswertung/getBerForRunId.m new file mode 100644 index 0000000..054c904 --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/getBerForRunId.m @@ -0,0 +1,32 @@ +function [berTable, foundBerFlag] = getBerForRunId(db, run_id) + % getBerForRunId Queries the BER data for the specified run_id. + % Inputs: + % db - The database handler object. + % run_id - The run ID for which to get the BER data. + % Outputs: + % berData - A table containing BER results for the given run ID. + + % Set up filter parameters to query the BER data for the specific run_id + filterParams = db.tables; + filterParams.Runs.run_id = run_id; % Filter by specific run_id + + % Define the fields to be retrieved from the database + selectedFields = {'Runs.run_id', 'BERs.ber_id', 'Equalizer.eq_id', 'Equalizer.eq_type', ... + 'BERs.ber', 'BERs.occurrence', 'Configurations.db_mode', ... + 'Configurations.pam_level', 'Configurations.bitrate', 'Configurations.symbolrate', ... + 'Configurations.fiber_length', 'Configurations.wavelength', ... + 'Configurations.precomp_amp', 'Measurements.power_rop', 'Measurements.power_laser', ... + 'Measurements.power_pd_in'}; + + % Query the database for the specified run_id + [berTable, ~] = db.queryDB(filterParams, selectedFields); + + if ~isnumeric(berTable.ber) + foundBerFlag = ~isnan(str2num(berTable.ber)); + else + foundBerFlag = 1; + end + + % Display information about the found BER entries + % fprintf('Found %d BER entries for run_id %d.\n', size(berTable, 1), run_id); +end diff --git a/projects/HighSpeedExperiment_2024/auswertung/only_show_precomp.m b/projects/HighSpeedExperiment_2024/auswertung/only_show_precomp.m new file mode 100644 index 0000000..fc66a1d --- /dev/null +++ b/projects/HighSpeedExperiment_2024/auswertung/only_show_precomp.m @@ -0,0 +1,85 @@ + +precomp_path = "C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\precomp"; +precomp_fn = "lab_high_speed"; +precomp_mode = 2; %0=do nothing ; 1= measure; 2=precomp active +db_precode = 1; +db_coding_approach = 1; + +fsym = 224e9; +fdac = 256e9; +random_key = 0; +M = 4; + +if (db_precode==1)&&(db_coding_approach==0) + + if M == 4 + pulsef=1; + precomp_amp_max = -50; + elseif M == 6 + pulsef=0; + precomp_amp_max = -50; + elseif M == 8 + pulsef=0; + precomp_amp_max = -50; + end + +elseif (db_precode==1)&&(db_coding_approach==1) + + if M == 4 + pulsef=1; + precomp_amp_max = -38; + pulsef = 1; + elseif M == 6 + pulsef=0; + precomp_amp_max = -38; + pulsef = 1; + elseif M == 8 + pulsef=0; + precomp_amp_max = -38; + pulsef = 1; + end + +elseif (db_precode==0)&&(db_coding_approach==0) + + if M == 4 + pulsef=1; + precomp_amp_max = -37; + pulsef = 1; + elseif M == 6 + pulsef=0; + precomp_amp_max = -34; + pulsef = 1; + elseif M == 8 + pulsef=0; + precomp_amp_max = -34; + pulsef = 0; + end +end + + +rcalpha = 0.05; +Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha); + + +Pamsource = PAMsource(... + "fsym",fsym,"M",M,"order",19,"useprbs",1,... + "fs_out",fdac,... + "applyclipping",0,"clipfactor",1.2,... + "applypulseform",pulsef,"pulseformer",Pform,... + "randkey",random_key,... + "db_precode",db_precode,"db_encode",db_coding_approach,... + "mrds_code",0,"mrds_blocklength",512); + +[Digi_sig,Symbols,Bits] = Pamsource.process(); + +Digi_sig.spectrum("displayname","TX with precomp","fignum",2223,"normalizeToNyquist",0,"normalizeTo0dB",0); + +precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',Digi_sig.fs); + +Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',precomp_amp_max,'loadPath',precomp_path,'fileName',precomp_fn); + +Digi_sig = Digi_sig.resample("fs_out",fdac); +Digi_sig= Digi_sig.normalize("mode","rms"); +Digi_sig.spectrum("displayname","TX After precomp","fignum",2223,"normalizeToNyquist",0,"normalizeTo0dB",0); + + diff --git a/projects/HighSpeedExperiment_2024/auswertung/runDSP.m b/projects/HighSpeedExperiment_2024/auswertung/runDSP.m index 91398b6..0d7fd55 100644 --- a/projects/HighSpeedExperiment_2024/auswertung/runDSP.m +++ b/projects/HighSpeedExperiment_2024/auswertung/runDSP.m @@ -1,23 +1,25 @@ - +tic basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; useGui = 0; - db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + +toc + if useGui filterParams = db.promptFilterParameters(); selectedFields = db.promptSelectFields(); else filterParams = db.tables; filterParams.Configurations = struct( ... - 'bitrate', [], ... - 'db_mode', [], ... - 'fiber_length', 10, ... + 'bitrate', 300e9, ... + 'db_mode', 0, ... + 'fiber_length', 1, ... 'interference_attenuation', [], ... 'interference_path_length', [], ... 'is_mpi', 0, ... - 'pam_level', [], ... + 'pam_level', 4, ... 'precomp_amp', [], ... - 'rop_attenuation', 0, ... + 'rop_attenuation', [], ... 'symbolrate', [], ... 'v_awg', [], ... 'v_bias', [], ... @@ -26,15 +28,30 @@ else % filterParams.Runs.run_id = 3303; %filterParams.Equalizer.eq_id = equalizer_structure.vnle; selectedFields = {'Runs.run_id','Runs.tx_bits_path', 'Runs.tx_symbols_path', 'Runs.rx_sync_path','Runs.rx_raw_path',... - 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp'}; + 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','BERs.ber'}; end -[dataTable,sql_query] = db.queryDB(filterParams, selectedFields); -fprintf('Found %d entries for requested Configuration. IDs are: %s \n',size(dataTable,1),jsonencode(dataTable.run_id)); +toc +[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 +fprintf('Found %d entries for requested Configuration. IDs are: %s \n \n',size(dataTable,1),jsonencode(dataTable.run_id(1:min(size(dataTable,1),100)))); + +toc + +fprintf('Processing: %d%%', 0); %2) Process Measurement Config for i = 1:size(dataTable,1) - fprintf('\n%s CURRENT ID: %d == %d KM == %s PAM %d == %d Gbit/s == %d nm %s \n \n', repmat('=', 1, 10), dataTable.run_id(i), dataTable.fiber_length(i) ,db_mode(dataTable.db_mode(i)), dataTable.pam_level(i) ,dataTable.bitrate(i).*1e-9,dataTable.wavelength(i), repmat('=', 1, 10)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line + + fprintf('\b\b\b\b%4d', i); % Backspace 3 characters, then overwrite + + [~, foundBerFlag] = getBerForRunId(db, dataTable.run_id(i)); + if foundBerFlag + continue + end + + fprintf('\n%s T: %f CURRENT ID: %d == %d KM == %s PAM %d == %d Gbit/s == %d nm %s \n \n', repmat('=', 1, 10), toc/60, dataTable.run_id(i), dataTable.fiber_length(i) ,db_mode(dataTable.db_mode(i)), dataTable.pam_level(i) ,dataTable.bitrate(i).*1e-9,dataTable.wavelength(i), repmat('=', 1, 10)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line % FROM NOW ON, ONE Run_id IS CHOSEN AND WILL BE DSP'd @@ -74,13 +91,13 @@ for i = 1:size(dataTable,1) %VNLE eq_vnle(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1); [eq_sig,eq_noise,ber_vnle(o),totalErrors] = vnle(eq_vnle(o),M,rx_sig,tx_symbols, tx_bits); - + %VNLE + PF + MLSE eq_mlse(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1); pf_(o) = Postfilter("ncoeff",2); mlse_(o) = MLSE("DIR",[0,0],"duobinary_output",0,"M",[],"trellis_states",[]); [eq_sig,eq_noise,ber_mlse(o),totalErrors] = vnle_postfilter_mlse(eq_mlse(o) , pf_(o), mlse_(o),M, rx_sig,tx_symbols, tx_bits); - + case db_mode.db_precoded %EQ targets DB => less precompensation; pre-coded @@ -141,7 +158,8 @@ for i = 1:size(dataTable,1) end end -fprintf('\n%s SIMULATION COMPLETE %s \n \n', repmat('=', 1, 35), repmat('=', 1, 35)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line + +fprintf('\n%s SIMULATION COMPLETE AFTER %f MINUTES %s \n \n', repmat('=', 1, 35), toc/60 ,repmat('=', 1, 35)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line diff --git a/projects/HighSpeedExperiment_2024/master_auswertung_10km.m b/projects/HighSpeedExperiment_2024/master_auswertung_10km.m index b297037..b6724f9 100644 --- a/projects/HighSpeedExperiment_2024/master_auswertung_10km.m +++ b/projects/HighSpeedExperiment_2024/master_auswertung_10km.m @@ -13,9 +13,14 @@ rop_atten_vals = wh.parameter.rop_atten.values; figure(18) tiledlayout(3, 3, 'TileSpacing', 'compact', 'Padding', 'compact'); +%CHANGE PAM FORMAT HERE (use 4,6,8) for M_choose = [8] sgtitle(['PAM',num2str(M_choose)]) for l = 1:numel(lambda_vals) + ber_vnle = []; + ber_vnle_mlse= []; + ber_db= []; + ber_db_enc= []; for b = 1:numel(bitrate_vals) cel = wh.getStoValue('ber_vnle',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(1),rop_atten_vals(1)); diff --git a/projects/HighSpeedExperiment_2024/single_auswertung_10km.m b/projects/HighSpeedExperiment_2024/single_auswertung_10km.m index 1aeadf0..830e60b 100644 --- a/projects/HighSpeedExperiment_2024/single_auswertung_10km.m +++ b/projects/HighSpeedExperiment_2024/single_auswertung_10km.m @@ -16,6 +16,10 @@ l = 6; for m = 1:numel(M_vals) sgtitle(['Lambda: ',num2str(lambda_vals(l)),' nm']) %for l = 1:numel(lambda_vals) + ber_vnle = []; + ber_vnle_mlse= []; + ber_db= []; + ber_db_enc= []; for b = 1:numel(bitrate_vals) M_choose = M_vals(m); diff --git a/projects/IMDD_base_system/filter_debug.m b/projects/IMDD_base_system/filter_debug.m deleted file mode 100644 index ad0a4be..0000000 --- a/projects/IMDD_base_system/filter_debug.m +++ /dev/null @@ -1,70 +0,0 @@ - -clear -%% Set Simulation Variables - -O = 18; %order of prbs -N = 2^(O-1); %length of prbs -[~,seed] = prbs(O,1); %initialize first seed of prbs - -% Modulation -M = 4; %PAM-M -bitpattern = zeros(N,log2(M)); - -% Symbol Rate -fsym = 112e9; - -% DAC Rate -fdac = 120e9; - -% Simulation oversampling rate "k"; -kover = 16; - -% ADC Rate -fadc = 256e9; - -% Simulation frequency in "analog domain" -fsimu = kover * fdac ; - - - -%% CONSTRUCT ALL CLASSES - -digimod = PAMmapper(M,0); - -pulsef = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.05); - -awg = AWG('preset','M8199B','fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); - -lp_laser = Filter('filtdegree',1,"f_cutoff",30e9,"fsamp",fdac,"filterType",filtertypes.bessel_inp); - - - -%% PROCESS - -% PRBS Generation -for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); -end - -% Build Inf. signal class -bits = Informationsignal(bitpattern); - -% Digi Mod -mod_out = digimod.map(bits); -% merken für EQ training -reference = mod_out; - -% shape shape -mod_out = pulsef.process(mod_out); -test = applyPulseShaping(reference.signal,fsym,fdac); - -% AWG -> ELECTRICAL DOMAIN -X = lp_laser.process(mod_out); -%X.spectrum(fsimu,"displayname",'AWG out','figurename','after AWG'); - - - - - - - diff --git a/projects/IMDD_base_system/imdd_example.m b/projects/IMDD_base_system/imdd_example.m new file mode 100644 index 0000000..809b6e7 --- /dev/null +++ b/projects/IMDD_base_system/imdd_example.m @@ -0,0 +1,220 @@ +function [ber] = imdd_example(varargin) + % BASIC IMDD Model... + % varargin is either empty or a struct, i.e.: + % + + + + curFolder = pwd; + funcFolder=fileparts(mfilename('fullpath')); + if ~isempty(funcFolder) + cd(funcFolder); + end + + % TX + M = 4; + fsym = 180e9; + f_nyquist = fsym/2; + apply_pulsef = 0; + fdac = 2*fsym;%256e9; + fadc = 2*fsym;%256e9; + fdac = 256e9; + fadc = 256e9; + random_key = 1; + db_precode = 0; + emulate_precode = 0; + discard_precode = 0; + db_encode = 0; + % duob_mode = db_mode.db_emulate; + emulate_db = 1; + rcalpha = 0.05; + kover = 16; + vbias_rel = 0.5; + u_pi = 2.9; + vbias = -vbias_rel*u_pi; + laser_wavelength = 1310; + laser_linewidth = 0; + tx_bw_nyquist = 1.5; + + % Channel + link_length = 1; + + % RX + rop = -8; + rx_bw_nyquist = 0.7; + + % EQ + eq_mode = equalizer_structure.vnle_pf_mlse; + ffe_order=[50,0,0]; + vnle_order=[50,7,7]; + dfe_order = [2 0 0]; + + len_tr = 4096*2; + mu_ffe = [0.0004 0.0004 0.0004]; + mu_dfe = 0.0004; + mu_dc = 0.00; + + dfe_ = sum(dfe_order)>0; + + % Parse optional input arguments + if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + end + else + error('Optional variables should be passed as a struct.'); + end + end + + %%%% TX Signal + Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha); + + [Digi_sig,Symbols,Bits] = PAMsource(... + "fsym",fsym,"M",M,"order",19,"useprbs",1,... + "fs_out",fdac,... + "applyclipping",0,"clipfactor",1.5,... + "applypulseform",apply_pulsef,"pulseformer",Pform,... + "randkey",random_key,... + "db_precode",db_precode,"db_encode",db_encode,... + "mrds_code",0,"mrds_blocklength",512).process(); + + Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1); + + %%%%% AWG + % El_sig = M8199A("kover",kover).process(Digi_sig); + El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig); + % El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0); + % El_sig = El_sig.setPower(0,"dBm"); + + %%%%% Low-pass el. components %%%%%% + El_sig = Filter('filtdegree',4,"f_cutoff",tx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig); + + %%%%% Electrical Driver Amplifier %%%%%% + El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig); + El_sig = El_sig.normalize("mode","oneone"); + + %%%%% MODULATE E/O CONVERSION %%%%%% + [Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1).process(El_sig); + + %%%%%% Fiber %%%%%% + Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig); + + %%%%%% ROP %%%%%% + Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig); + + + + %%%%%% PD Square Law %%%%%% + Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig); + + + %%%%%% Low-pass RX (PD, El. Connectors and Scope %%%%%% + Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(Rx_sig); + + % %%%%%% Low-pass Scope %%%%%% + %dactivated in scope module! + Lp_scpe = Filter('filtdegree',4,"f_cutoff",10e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true); + + % Rx_sig.spectrum("displayname",'Analog Rx Spectrum','fignum',100,'normalizeTo0dB',1); + + %%%%%% Scope %%%%%% + Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,... + "delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,... + "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... + "adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',0,'H_lpf',Lp_scpe).process(Rx_sig); + + % Scpe_sig.spectrum("displayname",'Digital (256 GSa/s) Rx Spectrum','fignum',100,'normalizeTo0dB',1); + + %%%%%% Sample to 2x fsym %%%%%% + Scpe_sig = Scpe_sig.resample("fs_in",fadc,"fs_out",2*fsym); + + %%%%%% Sync Rx signal with reference %%%%%% + [Scpe_sig,S] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym); + + Scpe_sig.spectrum("displayname",'Prior DSP (2x fsym) Spectrum','fignum',100,'normalizeTo0dB',1); + + %%% EQUALIZING + ber = struct(); + switch eq_mode + + case equalizer_structure.ffe + + %FFE + if db_precode + Bits_ = PAMmapper(M,0).demap(Symbols); + else + Bits_ = Bits; + end + + eq_ffe = EQ("Ne",ffe_order,"Nb",dfe_order,"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",1); + % eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); + % eq_ffe = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); + + [eq_sig,eq_noise,ber.ber_ffe,totalErrors] = vnle( eq_ffe,M,Scpe_sig ,Symbols, Bits_); + eq_noise.spectrum("displayname",'Noise Spectrum after FFE','fignum',41,'normalizeTo0dB',0); + + case equalizer_structure.vnle + + if db_precode + Bits_ = PAMmapper(M,0).demap(Symbols); + else + Bits_ = Bits; + end + + + %VNLE + eq_vnle = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_vnle,totalErrors] = vnle(eq_vnle,M,Scpe_sig ,Symbols, Bits_); + eq_noise.spectrum("displayname",'Noise Spectrum after VNLE','fignum',41,'normalizeTo0dB',0); + case equalizer_structure.vnle_pf_mlse + + if db_precode + Bits_ = PAMmapper(M,0).demap(Symbols); + else + Bits_ = Bits; + end + + %VNLE + PF + MLSE + eq_mlse = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + eq_mlse = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); + eq_mlse = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); + + pf_ = Postfilter("ncoeff",1); + mlse_ = MLSE("DIR",[0,0],"duobinary_output",0,"M",[],"trellis_states",[]); + [eq_sig,eq_noise,ber.ber_mlse,totalErrors] = vnle_postfilter_mlse(eq_mlse , pf_, mlse_,M, Scpe_sig ,Symbols, Bits_); + pf_.showFilter(eq_noise); + eq_noise.spectrum("displayname",'Noise Spectrum after VNLE+PF','fignum',41,'normalizeTo0dB',0); + case equalizer_structure.db_precoded + + %EQ targets DB => less precompensation; pre-coded + mlse_db_pre = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_pre = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_db,totalErrors] = duobinary_target(eq_db_pre, mlse_db_pre,M, Scpe_sig ,Symbols, Bits); + eq_noise.spectrum("displayname",'Noise Spectrum after DB','fignum',41,'normalizeTo0dB',0); + %->append BER to DB + + case equalizer_structure.db_encoded + + %db signaling => db encoded + mlse_db_enc = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_enc = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_db_enc,totalErrors] = duobinary_signaling(eq_db_enc, mlse_db_enc,M, Scpe_sig ,Symbols, Bits); + %->append BER to DB + end + + % fprintf('BER FFE: %.2e \n',ber.ber_mlse); + % % El_sig.spectrum("displayname",'Tx Spectrum','fignum',10,'normalizeTo0dB',1); + % Scpe_sig.spectrum("displayname",'Rx Spectrum','fignum',100,'normalizeTo0dB',1); + + + + + if ~isempty(curFolder) + cd(curFolder); + end + +end \ No newline at end of file diff --git a/projects/IMDD_base_system/imdd_example_live.mlx b/projects/IMDD_base_system/imdd_example_live.mlx new file mode 100644 index 0000000..bf780bb Binary files /dev/null and b/projects/IMDD_base_system/imdd_example_live.mlx differ diff --git a/projects/IMDD_base_system/imdd_it.m b/projects/IMDD_base_system/imdd_it.m new file mode 100644 index 0000000..86e8430 --- /dev/null +++ b/projects/IMDD_base_system/imdd_it.m @@ -0,0 +1,26 @@ + +% basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; +% db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + +uloops = struct; +uloops.bitrate = [300,330,360,390,420,450,480].*1e9; +uloops.M = 4; + +wh = DataStorage(uloops); +wh.addStorage("ber"); + +wh = submit_simulations(wh,db,"parallel",0,"simulation_mode",0); + +a = wh.getStoValue('ber', uloops.bitrate,uloops.M); +for i = 1:numel(a) + bers(i) = a{i}.ber_mlse; +end + +figure(2024) +hold on +plot(uloops.bitrate.*1e-9,bers); +yline(3.8e-3,'LineWidth',2,'DisplayName','3.8e-3'); +yline(2e-2,'LineWidth',2,'LineStyle','--','DisplayName','2e-2'); +beautifyBERplot() +legend + diff --git a/projects/IMDD_base_system/imdd_labdata_example.m b/projects/IMDD_base_system/imdd_labdata_example.m new file mode 100644 index 0000000..a36db10 --- /dev/null +++ b/projects/IMDD_base_system/imdd_labdata_example.m @@ -0,0 +1,172 @@ +% function [ber] = imdd_labdata_example(varargin) + +% TX + M = 4; + fsym = 224e9; + f_nyquist = fsym/2; + apply_pulsef = 0; + fdac = 2*fsym;%256e9; + fadc = 2*fsym;%256e9; + fdac = 256e9; + fadc = 256e9; + random_key = 1; + db_precode = 1; + db_encode = 0; + rcalpha = 0.05; + kover = 16; + vbias_rel = 0.5; + u_pi = 2.9; + vbias = -vbias_rel*u_pi; + laser_wavelength = 1293; + laser_linewidth = 0; + tx_bw_nyquist = 1.5; + +% Channel + link_length = 0; + +% RX + rop = -7.5; + rx_bw_nyquist = 1.5; + +% EQ + eq_mode = equalizer_structure.vnle_pf_mlse; + ffe_order=[50,0,0]; + vnle_order=[50,7,7]; + dfe_order = [0 0 0]; + + len_tr = 4096*2; + mu_ffe = [0.0004 0.0004 0.0004]; + mu_dfe = 0.0004; + mu_dc = 0.05; + + dfe_ = sum(dfe_order)>0; + + % + % % Parse optional input arguments + % if ~isempty(varargin) + % var_s = varargin{1}; + % if isstruct(var_s) + % fields = fieldnames(var_s); + % for i = 1:numel(fields) + % eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + % fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + % end + % else + % error('Optional variables should be passed as a struct.'); + % end + % end + + basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; + useGui = 0; + db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + filterParams = db.tables; + % filterParams.Runs.run_id = 2958; % no db + % filterParams.Runs.run_id = 2937; % no db + filterParams.Configurations = struct( ... + 'bitrate', 300e9, ... + 'db_mode', 0, ... + 'fiber_length', 1, ... + 'interference_attenuation', [], ... + 'interference_path_length', [], ... + 'is_mpi', 0, ... + 'pam_level', 4, ... + 'precomp_amp', [], ... + 'rop_attenuation', 0, ... + 'symbolrate', [], ... + 'v_awg', [], ... + 'v_bias', [], ... + 'wavelength', 1310 ... + ); + selectedFields = {'Runs.run_id','Runs.tx_bits_path', 'Runs.tx_symbols_path', 'Runs.rx_sync_path','Runs.rx_raw_path',... + 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','BERs.ber'}; + + [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 + fprintf('Found %d entries for requested Configuration. IDs are: %s \n \n',size(dataTable,1),jsonencode(dataTable.run_id(1:min(size(dataTable,1),100)))); + + tx_bits = load([basePath, char(dataTable.tx_bits_path(1))]); + tx_bits = tx_bits.Bits; + tx_symbols = load([basePath, char(dataTable.tx_symbols_path(1))]); + tx_symbols = tx_symbols.Symbols; + + rx_sync = load([basePath, char(dataTable.rx_sync_path(1))]); + rx_sync = rx_sync.S; + + fsym = tx_symbols.fs; + + %%%%%% Sample to 2x fsym %%%%%% + Scpe_sig = rx_sync{1}.resample("fs_in",rx_sync{1}.fs,"fs_out",2*fsym); + + %%%%%% Sync Rx signal with reference %%%%%% + [Scpe_sig,S] = Scpe_sig.tsynch("reference",tx_symbols,"fs_ref",fsym); + + Scpe_sig.spectrum("displayname",'Rx (Scpe+Sync+Resample)','fignum',100,'normalizeTo0dB',0); + + Scpe_sig = Filter('filtdegree',4,"f_cutoff",tx_symbols.fs.*0.6,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig); + + Scpe_sig.spectrum("displayname",'Rx (Scpe+Sync+Resample+LPF)','fignum',100,'normalizeTo0dB',0); + + %%% EQUALIZING + ber = struct(); + switch eq_mode + + case equalizer_structure.ffe + + %FFE + if db_precode + Bits_ = PAMmapper(M,0).demap(Symbols); + else + Bits_ = Bits; + end + + eq_ffe = EQ("Ne",ffe_order,"Nb",dfe_order,"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",1); + eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); + eq_ffe = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); + + [eq_sig,eq_noise,ber.ber_ffe,totalErrors] = vnle( eq_ffe,M,Scpe_sig ,Symbols, Bits_); + eq_noise.spectrum("displayname",'Noise Spectrum after FFE','fignum',41,'normalizeTo0dB',0); + + case equalizer_structure.vnle + %VNLE + eq_vnle = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_vnle,totalErrors] = vnle(eq_vnle,M,Scpe_sig ,Symbols, Bits_); + eq_noise.spectrum("displayname",'Noise Spectrum after VNLE','fignum',41,'normalizeTo0dB',0); + case equalizer_structure.vnle_pf_mlse + + %VNLE + PF + MLSE + eq_mlse = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + pf_ = Postfilter("ncoeff",1); + mlse_ = MLSE("DIR",[0,0],"duobinary_output",0,"M",[],"trellis_states",[]); + [eq_sig,eq_noise,ber.ber_mlse,totalErrors] = vnle_postfilter_mlse(eq_mlse , pf_, mlse_,M, Scpe_sig ,Symbols, Bits_); + pf_.showFilter(eq_noise); + + eq_noise.spectrum("displayname",'Noise Spectrum after VNLE+PF','fignum',41,'normalizeTo0dB',0); + + case equalizer_structure.db_precoded + + %EQ targets DB => less precompensation; pre-coded + mlse_db_pre = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_pre = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_db,totalErrors] = duobinary_target(eq_db_pre, mlse_db_pre,M, Scpe_sig ,Symbols, Bits); + eq_noise.spectrum("displayname",'Noise Spectrum after DB','fignum',41,'normalizeTo0dB',0); + %->append BER to DB + + case equalizer_structure.db_encoded + + %db signaling => db encoded + mlse_db_enc = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_enc = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,eq_noise,ber.ber_db_enc,totalErrors] = duobinary_signaling(eq_db_enc, mlse_db_enc,M, Scpe_sig ,Symbols, Bits); + %->append BER to DB + end + + fprintf('BER FFE: %.2e \n',ber.ber_mlse); + % % El_sig.spectrum("displayname",'Tx Spectrum','fignum',10,'normalizeTo0dB',1); + % Scpe_sig.spectrum("displayname",'Rx Spectrum','fignum',100,'normalizeTo0dB',1); + + + + + +% end \ No newline at end of file diff --git a/projects/IMDD_base_system/imdd_model.m b/projects/IMDD_base_system/imdd_model.m new file mode 100644 index 0000000..183f940 --- /dev/null +++ b/projects/IMDD_base_system/imdd_model.m @@ -0,0 +1,353 @@ +function [output] = imdd_model(simulation_mode,database,varargin) + + + + +%%% Change folder +curFolder = pwd; +funcFolder=fileparts(mfilename('fullpath')); +if ~isempty(funcFolder) + cd(funcFolder); +end + +%%% Run parameters +% TX +M = 4; +fsym = 180e9; +f_nyquist = fsym/2; +apply_pulsef = 1; +fdac = 256e9; +fadc = 256e9; +random_key = 1; + +db_precode = 1; +emulate_precode = 0; +discard_precode = 1; +db_encode = 0; +% duob_mode = db_mode.db_emulate; +emulate_db = 1; + +rcalpha = 0.05; +kover = 16; +vbias_rel = 0.5; +u_pi = 2.9; +vbias = -vbias_rel*u_pi; +laser_wavelength = 1310; +laser_linewidth = 0; +tx_bw_nyquist = 0.9; + +% Channel +link_length = 1; + +% RX +rop = -8; +rx_bw_nyquist = 0.7; + +% EQ +eq_mode = equalizer_structure.vnle_pf_mlse; +ffe_order=[50,0,0]; +vnle_order=[50,7,7]; +dfe_order = [2 0 0]; + +len_tr = 4096*2; +mu_ffe = [0.0004 0.0004 0.0004]; +mu_dfe = 0.0004; +mu_dc = 0.00; + +dfe_ = sum(dfe_order)>0; + +%%% change specific parameter if given in varargin +% Parse optional input arguments +if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + if isnumeric(fields{i}) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + else + eval([fields{i}, ' = ', 'var_s.(fields{',num2str(i),'})' , ';']); + end + + end + else + error('Optional variables should be passed as a struct.'); + end +end + +%%% run the simulation or measurement or ... + + +if simulation_mode + + fsym_ = floor( bitrate*1e-9./log2(M) ).*1e9; + + if fsym_ ~= fsym + fsym = fsym_; + fprintf('Adapted symbolrate to %d GBd, to match provided bitrate of %d GBit/s using PAM %d \n',fsym.*1e-9,bitrate.*1e-9, M); + end + + tx_simulation; + + + + Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig); + + rx_simulation; + + Scpe_cell{1} = Scpe_sig; + +else + + basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; + useGui = 0; + % db = DBHandler("pathToDB",[basePath,'silas_labor.db']); + filterParams = database.tables; + % filterParams.Runs.run_id = 2958; % no db + % filterParams.Runs.run_id = 2937; % no db + filterParams.Configurations = struct( ... + 'bitrate', bitrate, ... + 'db_mode', db_precode+db_encode, ... + 'fiber_length', link_length, ... + 'interference_attenuation', [], ... + 'interference_path_length', [], ... + 'is_mpi', 0, ... + 'pam_level', M, ... + 'precomp_amp', [], ... + 'rop_attenuation', 0, ... + 'symbolrate', [], ... + 'v_awg', [], ... + 'v_bias', [], ... + 'wavelength', 1310 ... + ); + + selectedFields = {'Runs.run_id','Runs.tx_bits_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','BERs.ber'}; + + [dataTable,sql_query] = database.queryDB(filterParams, selectedFields); + [~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices + dataTable = dataTable(uniqueIdx,:); % Extract unique configurations for each run_id + fprintf('Found %d entries for requested Configuration. IDs are: %s \n \n',size(dataTable,1),jsonencode(dataTable.run_id(1:min(size(dataTable,1),100)))); + + Tx_bits = load([basePath, char(dataTable.tx_bits_path(2))]); + Tx_bits = Tx_bits.Bits; + + Symbols = load([basePath, char(dataTable.tx_symbols_path(2))]); + Symbols = Symbols.Symbols; + + Scpe_load = load([basePath, char(dataTable.rx_sync_path(2))]); + Scpe_cell = Scpe_load.S; + + % Raw_signal = load([basePath, char(dataTable.rx_raw_path(1))]); + % Raw_signal = Raw_signal.Scpe_sig_raw; + + fsym = Symbols.fs; + +end + +output = struct(); + +for occ = 1:1%length(Scpe_cell) + + Scpe_sig = Scpe_cell{occ}; + + %%%%%% Sample to 2x fsym %%%%%% + Scpe_sig = Scpe_sig.resample("fs_out",2*fsym); + + %%%%%% Sync Rx signal with reference %%%%%% + [Scpe_sig,S] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym); + + % Scpe_sig.spectrum("displayname",'Rx (Scpe+Sync+Resample)','fignum',100,'normalizeTo0dB',0); + + Scpe_sig = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.6,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig); + + Scpe_sig.spectrum("displayname",'Rx (Scpe+Sync+Resample+LPF)','fignum',110,'normalizeTo0dB',0); + + Scpe_sig.plot("displayname",'Filtered Scope Signal','fignum',111,'clear',1); + + Scpe_sig.eye(fsym,M); + + + + %%% EQUALIZING + + switch eq_mode + + case equalizer_structure.ffe + + %FFE + if db_precode + Bits_ = PAMmapper(M,0).demap(Symbols); + else + Bits_ = Bits; + end + + eq_ffe = EQ("Ne",ffe_order,"Nb",dfe_order,"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",1); + % eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); + % eq_ffe = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); + + [eq_sig,Eq_noise,ber_ffe(occ),totalErrors] = vnle( eq_ffe,M,Scpe_sig ,Symbols, Bits_); + Eq_noise.spectrum("displayname",'Noise Spectrum after FFE','fignum',41,'normalizeTo0dB',0); + + fprintf('BER FFE: %.2e \n',ber_ffe(occ)); + + case equalizer_structure.vnle + + + + + + %VNLE + eq_vnle = EQ("Ne",vnle_order,"Nb",dfe_order,"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_sig,Eq_noise] = eq_vnle.process(Scpe_sig,Symbols); + + Eq_sig = PAMmapper(M,0).quantize(Eq_sig); + + if emulate_precode && db_precode == 0 + % emulation + Eq_sig = Duobinary().encode(Eq_sig); + Eq_sig = Duobinary().decode(Eq_sig); + + Symbols= Duobinary().encode(Symbols); + Symbols = Duobinary().decode(Symbols); + Tx_bits = PAMmapper(M,0).demap(Symbols); + elseif db_precode == 1 && db_encode == 0 && discard_precode == 1 + % normal dsp for precoded sequence + Tx_bits = PAMmapper(M,0).demap(Symbols); + + elseif db_precode == 1 && db_encode == 1 + error('not implemented') + + elseif db_precode == 1 && db_encode == 0 + Eq_sig = Duobinary().encode(Eq_sig); + Eq_sig = Duobinary().decode(Eq_sig); + end + + % M = numel(unique(tx_symbols.signal)); + Rx_bits = PAMmapper(M,0).demap(Eq_sig); + + [~,numErrors,ber,~] = calc_ber(Rx_bits.signal,Tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1); + + Eq_noise.spectrum("displayname",'Noise Spectrum after VNLE','fignum',41,'normalizeTo0dB',0); + + output.ber_vnle(occ) = ber; + + if 1c + figure(51); + clf + title(sprintf('DB coded PAM after EQ ; BER: %1.2e',M, ber )); + constellation = unique(Symbols.signal); + received = NaN(numel(constellation),length(Symbols)); + for lvl = 1:numel(constellation) + %Separate the equalized signal into the + %respective levels based on the actually + %transmitted level! + received(lvl,Symbols.signal==constellation(lvl)) = Eq_sig.signal(Symbols.signal==constellation(lvl)); + intermediate = received(lvl,:); + cnt(lvl) = numel(intermediate(~isnan(intermediate))); + hold on + histogram(received(lvl,:),1000,"EdgeAlpha",0,'DisplayName',['Lvl ',num2str(lvl),' | ',num2str(cnt(lvl)),' entries']); + end + legend + end + + Eq_sig.eye(fsym,M,"displayname",'Eye after EQ','fignum',52); + Eq_sig.spectrum("displayname",'Spectrum after EQ','fignum',53,'normalizeTo0dB',1); + Scpe_sig.spectrum("displayname",'Spectrum before EQ','fignum',53,'normalizeTo0dB',1); + fprintf('BER FFE: %.2e \n',ber); + + + + + + case equalizer_structure.vnle_pf_mlse + + + %VNLE + PF + MLSE + eq_mlse = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + % eq_mlse = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",1,"mu_dc",0.05); + % eq_mlse = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); + % eq_mlse = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); + + pf_ = Postfilter("ncoeff",2); + mlse_ = MLSE("DIR",[0,0],"duobinary_output",0,"M",[],"trellis_states",[]); + + %FFE or VNLE + [Eq_sig,Eq_noise] = eq_mlse.process(Scpe_sig,Symbols); + + Eq_sig = pf_.process(Eq_sig,Eq_noise); + + %M = numel(unique(tx_symbols.signal)); + mlse_.DIR = pf_.burg_coeff; + mlse_.trellis_states = PAMmapper(M,0).levels; + mlse_.M = M; + + Eq_sig = mlse_.process(Eq_sig); + pf_.showFilter(Eq_noise); + % Eq_noise.spectrum("displayname",'Noise Spectrum after VNLE+PF','fignum',41,'normalizeTo0dB',0); + + if emulate_precode && db_precode == 0 + % emulation + Eq_sig = Duobinary().encode(Eq_sig); + Eq_sig = Duobinary().decode(Eq_sig); + + Symbols= Duobinary().encode(Symbols); + Symbols = Duobinary().decode(Symbols); + Tx_bits = PAMmapper(M,0).demap(Symbols); + elseif db_precode == 1 && db_encode == 0 && discard_precode == 1 + % normal dsp for precoded sequence + Tx_bits = PAMmapper(M,0).demap(Symbols); + + elseif db_precode == 1 && db_encode == 1 + error('not implemented') + + elseif db_precode == 1 && db_encode == 0 + Eq_sig = Duobinary().encode(Eq_sig); + Eq_sig = Duobinary().decode(Eq_sig); + end + + Rx_bits = PAMmapper(M,0).demap(Eq_sig); + + [~,numErrors,ber,~] = calc_ber(Rx_bits.signal,Tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1); + + output.ber_mlse(occ) = ber; + output.pf_taps(occ,:) = pf_.burg_coeff; + + + fprintf('BER MLSE: %.2e \n',ber); + + case equalizer_structure.db_precoded + + %EQ targets DB => less precompensation; pre-coded + mlse_db_pre = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_pre = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,Eq_noise,ber_db(occ),totalErrors] = duobinary_target(eq_db_pre, mlse_db_pre,M, Scpe_sig ,Symbols, Bits); + Eq_noise.spectrum("displayname",'Noise Spectrum after DB','fignum',41,'normalizeTo0dB',0); + %->append BER to DB + + fprintf('BER VNLE+DB: %.2e \n',ber_db(occ)); + + case equalizer_structure.db_encoded + + %db signaling => db encoded + mlse_db_enc = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels); + eq_db_enc = EQ("Ne",vnle_order,"Nb",dfe_order,"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",1); + [eq_sig,Eq_noise,ber_db_enc,totalErrors] = duobinary_signaling(eq_db_enc, mlse_db_enc,M, Scpe_sig ,Symbols, Bits); + %->append BER to DB + + fprintf('BER DB: %.2e \n',ber_db_enc(occ)); + end + autoArrangeFigures; + + +end + + + +if ~isempty(curFolder) + cd(curFolder); +end + +end \ No newline at end of file diff --git a/projects/IMDD_base_system/imddmodel.m b/projects/IMDD_base_system/imddmodel.m deleted file mode 100644 index b3879bf..0000000 --- a/projects/IMDD_base_system/imddmodel.m +++ /dev/null @@ -1,227 +0,0 @@ -function output = imddmodel(sir,dcmode) - -for realiz = 1:3 - - rng(realiz); - - %% Set Simulation Variables - delay = 0;10+(10*realiz); %mpi delay in meter - - fiblen = 0; %main link in km - - laser_linewidth =0e6; - - O = 18; %order of prbs - N = 2^(O-1); %length of prbs - [~,seed] = prbs(O,1); %initialize first seed of prbs - - % Modulation - M = 4; %PAM-M - bitpattern = zeros(N,log2(M)); - - % Symbol Rate - fsym = 112e9; - - % DAC Rate - fdac = 120e9; - - % Simulation oversampling rate "k"; - kover = 16; - - % ADC Rate - fadc = 256e9; - - % Simulation frequency in "analog domain" - fsimu = kover * fdac ; - - - - %% B) CONSTRUCT ALL CLASSES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - digimod = PAMmapper(M,0); - - pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.027); - - awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); - - lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); - - u_pi = 3.5; - vbias = (0.5*u_pi)-u_pi; - extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth); - - fib = Fiber("fsimu",fdac*kover,"fiber_length",fiblen,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0); - - reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir); - reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",delay/1000,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0); - - opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-8); - - phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20); - - lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); - - scp = Scope("fsimu",fdac*kover,"fadc",fadc,... - "delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,... - "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... - "adcresolution",6,"quantbuffer",0.1,'block_dc',1); - - eq = EQ("K",2,"plottrain",0,"plotfinal",0,... - "training_length",4096,"training_loops",2,... - "Ne",[50,5,3],"Nb",[3,2,2],... - "DCmu",0.05,"DDmu",[0.0004 0.0005 0.0006 0.0007 ],"DFEmu",0.005,"FFEmu",0.005,... - "dd_loops",2,"epsilon",[10 100 1000 ],"M",2,... - "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0); - - eq2 = EQ_silas("Ne",[20,0,0],"Nb",[3,0,0],"trainlength",4096,"mu_dc_dd",0.005,"mu_dc_train",0.05,... - "mu_ffe_train",0.005,"mu_combined_dd",[0.0004 0.0006 0.0003 0.005],"ddloops",3,"dcmode",dcmode); - - - %% C) PROCESS TX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) PRBS Generation - for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); - end - - % 2 ) Build Inf. signal class - bits = Informationsignal(bitpattern); - - % 3) Digi modulation -> PAM-M signal - digimod_out = digimod.map(bits); - - % 4) Pulse shaping -> racos - X = pulseform.process(digimod_out); - - % 5) AWG (lowpass, quantization, sample and hold) - X = awg.process(X); - - % 6) Lowpass behavior of laser and hf-cable? why twice? - X = lp_laser.process(X); - X = lp_laser.process(X); - - % 7) Normalize signal - X = X.normalize("mode","oneone"); - X.signal = X.signal .* 1.3800; - - - - %% D) PROCESS OPTICAL CHANNEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Laser; Modulation -> OPTICAL DOMAIN - [X,extmodlaser] = extmodlaser.process(X); - - % 2) Main fiber propagation - X = fib.process(X); - - if delay ~= 0 - - % 3) Reflection - % Reflection is just an attenuation - R = reflectionpoint.process(X); - - % Propagate back and forth (actual fiber propagation) - R = reflectionprop.process(R); - - % Delay the reflected signal - [R,n] = R.delay("delay_meter",delay); - - % Add together - X.signal = X.signal(n:end); - R.signal = R.signal(n:end); - - %disp(['SIR ',num2str(10*log10(X.power/R.power))]); - - X = X+R; - - % 4) Equalize - % cut reference signal to correct length (nessecary due to MPI delay) - digimod_out.signal = digimod_out.signal(round(n * fsym/fsimu) : end,:); - bitpattern = bitpattern(round(n * fsym/fsimu):end,:); - end - - % 4) Attenuation - X = opticatten.process(X); - % X = edfaamp.process(X); - - % 5) Photo Diode -> ELECTRICAL DOMAIN - X = phdiode.process(X); - X = lp_diode.process(X); - - - %% E) PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) - X = scp.process(X); - - % 2) Resample to 2x symbol rate - X = X.resample("fs_out",2*fsym,"fs_in",fadc); - - % 3) Normalize - Eq_in = X.normalize("mode","rms"); - - - - % MPI reduction DC removal BEFORE EQ - wl = 3000; % symbols - Eq_in.signal = Eq_in.signal - 1/wl .* movsum( Eq_in.signal,[wl/2,wl/2]); - - % Equalize Signal - [Eq_out] = eq2.process(Eq_in,digimod_out); - - - - - %% A1: MPI reduction DC removal - wl = 1000; % symbols - yk_dcsm = Eq_out; - yk_dcsm.signal = Eq_out.signal - 1/wl .* movsum( Eq_out.signal,[wl/2,wl/2]); - - %% A2: MPI reduction Level wise error removal - yk_lvsm = Eq_out; - yk_lvlp = Eq_out; - pre_decision_level_uni = digimod.decide_pamlevel(Eq_out); - pre_decision_level_bi = ( pre_decision_level_uni*2-3 ) .* 1/sqrt(5); - - e = Eq_out.signal - pre_decision_level_bi; - - lp_mpi = Filter('filtdegree',1,"f_cutoff",2e6,"fsamp",fsym,"filterType",filtertypes.bessel_inp); - - filtered = lp_mpi.process(e); - - wl = 30; % symbols - smoothed = ( 1/wl .* movsum(e,[wl/2,wl/2]) ); - - % remove interference - for level = 0:3 - yk_lvsm.signal(pre_decision_level_uni==level) = yk_lvsm.signal(pre_decision_level_uni==level) - smoothed(pre_decision_level_uni==level); - yk_lvlp.signal(pre_decision_level_uni==level) = yk_lvlp.signal(pre_decision_level_uni==level) - filtered(pre_decision_level_uni==level); - end - - %% PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Digi Demod - d_bm = digimod.demap(Eq_out); - d_dcsm = digimod.demap(yk_dcsm); - d_lvsm = digimod.demap(yk_lvsm); - d_lvlp = digimod.demap(yk_lvlp); - - % 2) BER - - dbit = length(d_bm.signal)-length(bitpattern); - - [~,errors_bm,ber_bm(realiz),loc] = calc_ber(d_bm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",1); - [~,errors_dcsm,ber_dcsm(realiz)] = calc_ber(d_dcsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - [~,errors_lvsm,ber_lvsm(realiz)] = calc_ber(d_lvsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - [~,errors_lvlp,ber_lvlp(realiz)] = calc_ber(d_lvlp.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - - -end - -output.ber_bm = mean(ber_bm); -output.ber_dcsm = mean(ber_dcsm); -output.ber_lvsm = mean(ber_lvsm); -output.ber_lvlp = mean(ber_lvlp); - - -end \ No newline at end of file diff --git a/projects/IMDD_base_system/parameters.m b/projects/IMDD_base_system/parameters.m new file mode 100644 index 0000000..e329a37 --- /dev/null +++ b/projects/IMDD_base_system/parameters.m @@ -0,0 +1,46 @@ +% TX + M = 4; + fsym = 180e9; + f_nyquist = fsym/2; + apply_pulsef = 0; + fdac = 2*fsym;%256e9; + fadc = 2*fsym;%256e9; + fdac = 256e9; + fadc = 256e9; + random_key = 1; + db_precode = 0; + emulate_precode = 0; + discard_precode = 0; + db_encode = 0; + % duob_mode = db_mode.db_emulate; + emulate_db = 1; + rcalpha = 0.05; + kover = 16; + vbias_rel = 0.5; + u_pi = 2.9; + vbias = -vbias_rel*u_pi; + laser_wavelength = 1310; + laser_linewidth = 0; + tx_bw_nyquist = 1.5; + +% Channel + link_length = 1; + +% RX + rop = -8; + rx_bw_nyquist = 0.7; + +% EQ + eq_mode = equalizer_structure.vnle_pf_mlse; + ffe_order=[50,0,0]; + vnle_order=[50,7,7]; + dfe_order = [2 0 0]; + + len_tr = 4096*2; + mu_ffe = [0.0004 0.0004 0.0004]; + mu_dfe = 0.0004; + mu_dc = 0.00; + + dfe_ = sum(dfe_order)>0; + + \ No newline at end of file diff --git a/projects/IMDD_base_system/run_loop.m b/projects/IMDD_base_system/run_loop.m deleted file mode 100644 index 2041d50..0000000 --- a/projects/IMDD_base_system/run_loop.m +++ /dev/null @@ -1,208 +0,0 @@ - -clear - -sir_loop = [-25:2:-13]; -sir_loop = 0; -lw_loop = [1,2,3]; - -data = cell(length(sir_loop),length(lw_loop)); - -iterations=size(data); - -parfor ix = 1:numel(data) - - [u1,u2] = ind2sub(iterations,ix); - - output = imddmodel(sir_loop(u1),lw_loop(u2)); - - data{ix} = output; - -end - -for sir = 1:size(data,1) - for lw = 1:size(data,2) - ber_bm(sir,lw) = data{sir,lw}.ber_bm; - ber_dcsm(sir,lw) = data{sir,lw}.ber_dcsm; - ber_lvsm(sir,lw) = data{sir,lw}.ber_lvsm; - ber_lvlp(sir,lw) = data{sir,lw}.ber_lvlp; - end -end - -col = [ 0.6510 0.8078 0.8902 - 0.6980 0.8745 0.5412 - 0.9922 0.7490 0.4353]; -figure(22) -for l = 1:numel(lw_loop) - hold on - plot(sir_loop,ber_bm(:,l),'DisplayName',['DC mode:', num2str(lw_loop(l)),', Linewidth= 50 MHz'],'Marker','o','MarkerFaceColor',col(l,:),'Color',col(l,:),'LineWidth',2,'LineStyle','--'); -end -set(gca,'yscale','log'); -yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off'); -set(gca,'xdir','reverse'); - - - -%% Plot -col = linspecer(8); -figure(1) -hold on -m = ["x","o","pentagram","hexagram","*","+"]; -cnt = 1; -for d = 1%:size(data,2) - for dc = 1:size(data,1) - for lw = 1:size(data,3) - ber_bm(dc,d,lw) = (data{dc,d,lw}.ber_bm); - ber_dcsm(dc,d,lw) = data{dc,d,lw}.ber_dcsm; - ber_lvsm(dc,d,lw) = data{dc,d,lw}.ber_lvsm; - ber_lvlp(dc,d,lw) = (data{dc,d,lw}.ber_lvlp); - end - end - i = 1; - comm_dn = [];% ['EQ DC Tap: ',num2str(dc_tap_loop(d)),' m']; - title("Dependency on Laser Linewidth; B2B; Delay : 2*50m") - plot(lw_loop*1e-6,mean(squeeze(ber_bm(1:end,d,:)),1),"LineWidth",1.2,"Marker",m(1),"MarkerSize",5,'Color',col(cnt,:),'DisplayName',[' ',comm_dn]); - plot(lw_loop*1e-6,mean(squeeze(ber_dcsm(1:end,d,:)),1),"LineWidth",1,"Marker",m(1+4),"MarkerSize",5,'LineStyle','--','Color',col(cnt,:),'DisplayName',['DC smoothing ',comm_dn],'HandleVisibility','on'); - plot(lw_loop*1e-6,mean(squeeze(ber_lvsm(1:end,d,:)),1),"LineWidth",1.2,"Marker",m(1+1),"MarkerSize",5,'LineStyle',':','Color',col(cnt,:),'DisplayName',['Lvl Smoothing ',comm_dn],'HandleVisibility','on'); - plot(lw_loop*1e-6,mean(squeeze(ber_lvlp(1:end,d,:)),1),"LineWidth",1,"Marker",m(1+3),"MarkerSize",5,'LineStyle','-.','Color',col(cnt,:),'DisplayName',['Lvl Lowpass ',comm_dn],'HandleVisibility','on'); - set(gca,'yscale','log'); - set(gca,'xscale','log'); - %xticklabels([10 100 1000 10000]); - grid minor - yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off'); - ylim([1e-3 4e-2]); - ylabel("BER"); - xlabel("Linewidth in MHz") - legend - cnt = cnt+1; -end - - -figure(1) -contour(lw_loop,sir_loop,thres_a0,16:0.4:21,'LineWidth',2,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB"); -clim([16 21]); -ylabel("Bandwidth in Multiples of Linewidth"); -xlabel("Linewidth in MHz"); -% set(gca,'yscale','log'); -grid minor -title("MPI removal - Optimization of Lowpass Filter Bandwidth") - -figure(2) -contour(lw_loop,sir_loop([1:10,12:end]),thres_a0([1:10,12:end],:),16:0.3:21,'LineWidth',2,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB"); -clim([16 21]); -ylabel("Window Length"); -xlabel("Linewidth in MHz"); -set(gca,'yscale','log'); -grid minor -title("MPI removal - Optimization of Averaging Window Length") - - - -%% Plot Winlen Contour -hdfec = 3.8e-3.*ones(size(sir_loop)); - -for dc = 1:size(data,2) - for lw = 1:size(data,3) - for s = 1:size(data,1) - ber_lvlp(s,dc,lw) = data{s,dc,lw}.ber_dcsm; - % ber_dcsm(wl,lw,s) = data{wl,s,lw}.ber_dcsm; - end - - a_bm = InterX([sir_loop;squeeze(ber_lvlp(:,dc,lw))'],[sir_loop;hdfec]); - % a_dcsm = InterX([sirloop;squeeze(ber_dcsm(wl,lw,:))'],[sirloop;hdfec]); - try - thres_a0(dc,lw) = -a_bm(1); - %thres_a1(wl,lw) = -a_dcsm(1); - catch - thres_a0(dc,lw) = NaN; - %thres_a1(wl,lw) = NaN; - end - - end -end - -figure(1) -contour(lw_loop,bw_loop,thres_a0,14:0.2:21,'LineWidth',1.5,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB"); -a = flip(cbrewer2('seq','Spectral',32)); -a = [a(1:12,:); a(22:end,:)]; -colormap(a); -clim([16 21]); -ylabel("Window Length"); -xlabel("Linewidth in MHz"); -yticks(bw_loop); -yticklabels(bw_loop); -set(gca,'yscale','log'); -set(gca,'xscale','log'); -grid minor - - - - -%% Plot DC Tap Contour -hdfec = 3.8e-3.*ones(size(bw_loop)); -thres_a0 = zeros(size(ber,1),size(ber,3)); -thres_a1 = zeros(size(ber,1),size(ber,3)); -for dc = 1:size(ber,1) - for lw = 1:size(ber,3) - a_lvsm = InterX([bw_loop;ber(dc,:,lw)],[bw_loop;hdfec]); - thres_a0(dc,lw) = -a_lvsm(1); - - a1 = InterX([bw_loop;ber_a1(dc,:,lw)],[bw_loop;hdfec]); - thres_a1(dc,lw) = -a1(1); - end -end - -figure(1) -subplot(2,1,1) -contour(lw_loop,sir_loop,thres_a0,16:0.5:21,'LineWidth',3,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB"); -clim([16 21]); -ylabel("DC Tap"); -xlabel("Linewidth in MHz"); -set(gca,'yscale','log'); -grid minor -subplot(2,1,2) -contour(lw_loop,sir_loop,thres_a1,16:0.5:21,'LineWidth',3,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB"); -clim([16 21]); -ylabel("DC Tap"); -xlabel("Linewidth in MHz"); -set(gca,'yscale','log'); -grid minor - -%% Plot Curves of required SIR to see the minimum a bit better -col = flip(cbrewer2('seq','Spectral',16)); -col = col([1:4, 10:end],:); -figure(2) -hold on -for lw = [size(ber,3):-2:2 2 1] - plot(sir_loop,thres_a0(:,lw),'DisplayName',[' Linewidth: ',num2str(lw_loop(lw)*1e-6), ' MHz'],'Color',col(lw,:),'Marker','o','MarkerFaceColor',col(lw,:),'LineWidth',2); - set(gca,'xscale','log'); -end -xlabel("DC Tap Value"); -ylabel("Required SIR to rech FEC in dB"); - -%% -col = linspecer(7); -figure(3) -cnt=1; -for lw = [1,2,11] - - for i = 1:length(sir_loop)-1 - - subplot(1,3,cnt) - hold on - plot(-1.*bw_loop,ber(i,:,lw),"LineWidth",2,"Marker","o","MarkerSize",5,'Color',col(i,:),'DisplayName',['DC tap ',num2str(sir_loop(i))]); - plot(-1.*bw_loop,ber_a1(i,:,lw),"LineWidth",2,"Marker","x","MarkerSize",5,'LineStyle','--','Color',col(i,:),'DisplayName',['A1. DC tap ',num2str(sir_loop(i))]); - yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off'); - set(gca,'yscale','log'); - grid minor - - xlim([15,30]); - ylim([1e-4,1e-2]); - xlabel("SIR in dB"); - ylabel("BER"); - title(['BER for different SIR;',' Linewidth: ',num2str(lw_loop(lw)*1e-6), ' MHz']) - text(25,4.2e-3,"FEC $3.8 e^{-3}$"); - end - cnt = cnt+1; -end -legend - diff --git a/projects/IMDD_base_system/rx_simulation.m b/projects/IMDD_base_system/rx_simulation.m new file mode 100644 index 0000000..f105bf4 --- /dev/null +++ b/projects/IMDD_base_system/rx_simulation.m @@ -0,0 +1,24 @@ + + + %%%%%% ROP %%%%%% + Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig); + + + %%%%%% PD Square Law %%%%%% + Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig); + + + %%%%%% Low-pass RX (PD, El. Connectors and Scope %%%%%% + Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(Rx_sig); + + % %%%%%% Low-pass Scope %%%%%% + Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true); + + % Rx_sig.spectrum("displayname",'Analog Rx Spectrum','fignum',100,'normalizeTo0dB',1); + + %%%%%% Scope %%%%%% + Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,... + "delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,... + "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... + "adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig); + diff --git a/projects/IMDD_base_system/setup_simulation.m b/projects/IMDD_base_system/setup_simulation.m deleted file mode 100644 index 324a409..0000000 --- a/projects/IMDD_base_system/setup_simulation.m +++ /dev/null @@ -1,399 +0,0 @@ - - -lw = [0.1e6 1e6 10e6]; - -for lp = 1 - - rng(9); - - %% A) Set Simulation Variables - - sir = -18; - delay = 50; %mpi delay in meter - - fiblen = 0; %main link in km - - laser_linewidth =5e6; - - O = 19; %order of prbs - N = 2^(O-1); %length of prbs - [~,seed] = prbs(O,1); %initialize first seed of prbs - - % Modulation - M = 4; %PAM-M - bitpattern = zeros(N,log2(M)); - - % Symbol Rate - fsym = 112e9; - - % DAC Rate - fdac = 120e9; - - % Simulation oversampling rate "k"; - kover = 16; - - % ADC Rate - fadc = 256e9; - - % Simulation frequency in "analog domain" - fsimu = kover * fdac ; - - - - %% B) CONSTRUCT ALL CLASSES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - digimod = PAMmapper(M,0); - - pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.027); - - awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); - - lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); - - u_pi = 3.5; - vbias = (0.5*u_pi)-u_pi; - extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1310,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth); - - fib = Fiber("fsimu",fdac*kover,"fiber_length",fiblen,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0); - - reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir); - reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",delay/1000,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0); - - opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-8); - - phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20); - - lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); - - scp = Scope("fsimu",fdac*kover,"fadc",fadc,... - "delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,... - "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... - "adcresolution",6,"quantbuffer",0.1,'block_dc',1); - - eq = EQ("K",2,"plottrain",0,"plotfinal",0,... - "training_length",4096,"training_loops",2,... - "Ne",[50,5,3],"Nb",[3,0,0],... - "DCmu",0.05,"DDmu",[0.0004 0.0005 0.0006 0.0007 ],"DFEmu",0.005,"FFEmu",0.00,... - "dd_loops",2,"epsilon",[10 100 1000 ],"M",2,... - "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0); - - eq = EQ_silas("Ne",[50,5,3],"Nb",[2,0,0],"trainlength",4096,... - "sps",2,... - "mu_dc_dd",0.05,... - "mu_dc_train",0.05,... - "mu_ffe_train",0,... - "mu_dfe_train",0.005,... - "mu_ffe_dd",[0.0004 0.0004 0.0004],... - "mu_dfe_dd",0.005,... - "ddloops",3,... - "trainloops",4,... - "dcmode",1); - - - %% C) PROCESS TX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) PRBS Generation - for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); - end - - % 2 ) Build Inf. signal class - bits = Informationsignal(bitpattern); - - % 3) Digi modulation -> PAM-M signal - digimod_out = digimod.map(bits); - - % 4) Pulse shaping -> racos - X = pulseform.process(digimod_out); - - % 5) AWG (lowpass, quantization, sample and hold) - X = awg.process(X); - - % 6) Lowpass behavior of laser and hf-cable? why twice? - X = lp_laser.process(X); - % X = lp_laser.process(X); - - % 7) Normalize signal - X = X.normalize("mode","oneone"); - X.signal = X.signal .* 1.3800; - - - %% D) PROCESS OPTICAL CHANNEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Laser; Modulation -> OPTICAL DOMAIN - [X,extmodlaser] = extmodlaser.process(X); - - % 2) Main fiber propagation - X = fib.process(X); - - if delay ~= 0 - % 3) Reflection - % Reflection is just an attenuation - R = reflectionpoint.process(X); - - % Propagate back and forth (actual fiber propagation) - R = reflectionprop.process(R); - - % Delay the reflected signal - [R,n] = R.delay("delay_meter",delay); - - % Add together - col = cbrewer2('qual','Paired',8); - - xax = (1:X.length);% / fsimu * (physconst("LightSpeed")/1.4677); - xax_sec = (1:X.length) / fsimu .* 1e6;%* (physconst("LightSpeed")/1.4677); - xax_sec = xax_sec(n:end).'; - thresh = pi/4; - phaseX = phase(X.signal(n:end)); - phaseR = phase(R.signal(n:end)); - phasediff = wrapToPi(phaseX-phaseR); - [pos_high] = find(abs(phasediff)>thresh); - [pos_low] = find(abs(phasediff)<=thresh); - - - figure(6);hold on;histogram(phaseX-phaseR,500,'EdgeAlpha',0) - - figure() - subplot(3,1,1) - scatter(xax_sec.',wrapToPi(phaseX),4,'.','MarkerEdgeColor',col(2,:),'DisplayName','Desired Signal') - hold on - scatter(xax_sec,wrapToPi(phaseR),4,'.','MarkerEdgeColor',col(1,:),'DisplayName','Reflected Signal') - hold on - lg = legend; - lg.Location = "southwest"; - xlim([xax_sec(1) xax_sec(end)]); - xlabel('time in $\mu$s') - ylim([-pi pi]); - yticks([-pi 0 pi]) - yticklabels({'$-\pi$',0, '$\pi$'}) - ylabel('$\phi$') - - subplot(3,1,2) - scatter(xax_sec(pos_low),phasediff(pos_low),4,'.','MarkerEdgeColor',col(5,:),'DisplayName','Phase Difference') - hold on - scatter(xax_sec(pos_high),phasediff(pos_high),4,'.','MarkerEdgeColor',col(2,:),'HandleVisibility','off') -% yline(thresh,'LineWidth',2,'LineStyle','-','HandleVisibility','off') -% yline(-thresh,'LineWidth',2,'LineStyle','-','HandleVisibility','off') - lg = legend; - lg.Location = "southwest"; - xlabel('time in $\mu$s') - xlim([xax_sec(1) xax_sec(end)]); - ylim([-pi pi]); - yticks([-pi 0 pi]) - yticklabels({'$-\pi$',0, '$\pi$'}) - ylabel('$\Delta \phi$') - - - X.signal = X.signal(n:end); - R.signal = R.signal(n:end); - X1 = X; - X = X+R; - - subplot(3,1,3) - scatter(xax_sec(pos_low),abs(X.signal(pos_low).^2)*1000,4,'.','MarkerEdgeColor',col(5,:),'DisplayName','Constructive Interference'); - hold on - scatter(xax_sec(pos_high),abs(X.signal(pos_high).^2)*1000,4,'.','MarkerEdgeColor',col(2,:),'DisplayName','Destructive Interference'); - %scatter(xax_sec(pos_high),abs(X1.signal(pos_high).^2)*1000,4,'.','MarkerEdgeColor',col(1,:),'MarkerFaceAlpha',0.3,'DisplayName','Destructive Interference'); - xlim([xax_sec(1) xax_sec(end)]); - xlabel('time in $\mu$s') - lg = legend; - lg.Location = "southwest"; - ylabel('Optical power in mW'); - - - - - disp(['SIR ',num2str(10*log10(X.power/R.power))]); - - % cut reference signal to correct length (nessecary due to MPI delay) - digimod_out.signal = digimod_out.signal(round(n * fsym/fsimu) : end,:); - - bitpattern = bitpattern(round(n * fsym/fsimu):end,:); - - end - - -% plot(angle(R.signal)) - - % 4) Attenuation - X = opticatten.process(X); - - - % 5) Photo Diode -> ELECTRICAL DOMAIN - X = phdiode.process(X); - X = lp_diode.process(X); - - - %% E) PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) - X = scp.process(X); - - % 2) Resample to 2x symbol rate - X = X.resample("fs_out",2*fsym,"fs_in",fadc); - - % 3) Normalize - Eq_in = X.normalize("mode","rms"); - - % 4) Equalize - - % MPI reduction DC removal BEFORE EQ - wl = 3000; % symbols - Eq_in.signal = Eq_in.signal - 1/wl .* movsum( Eq_in.signal,[wl/2,wl/2]); - - % Equalize Signal - [Eq_out] = eq.process(Eq_in,digimod_out); - - - - %% A1: MPI reduction DC removal - wl = 1000; % symbols - yk_dcsm = Eq_out; - yk_dcsm.signal = Eq_out.signal - 1/wl .* movsum( Eq_out.signal,[wl/2,wl/2]); - - %% A2: MPI reduction Level wise error removal - yk_lvsm = Eq_out; - yk_lvlp = Eq_out; - pre_decision_level_uni = digimod.decide_pamlevel(Eq_out); - pre_decision_level_bi = ( pre_decision_level_uni*2-3 ) .* 1/sqrt(5); - - e = Eq_out.signal - pre_decision_level_bi; - - lp_mpi = Filter('filtdegree',1,"f_cutoff",2e6,"fsamp",fsym,"filterType",filtertypes.bessel_inp); - - filtered = lp_mpi.process(e); - - wl = 30; % symbols - smoothed = ( 1/wl .* movsum(e,[wl/2,wl/2]) ); - - % remove interference - for level = 0:3 - yk_lvsm.signal(pre_decision_level_uni==level) = yk_lvsm.signal(pre_decision_level_uni==level) - smoothed(pre_decision_level_uni==level); - yk_lvlp.signal(pre_decision_level_uni==level) = yk_lvlp.signal(pre_decision_level_uni==level) - filtered(pre_decision_level_uni==level); - end - - % Calc EVM - - evm_bm = calc_evm(Eq_out.signal, pre_decision_level_bi); - evm_dcsm = calc_evm(yk_dcsm.signal, pre_decision_level_bi); - evm_lsm = calc_evm(yk_lvsm.signal, pre_decision_level_bi); - evm_llp = calc_evm(yk_lvlp.signal, pre_decision_level_bi); - - % figure(1);bar([evm_bm' evm_dcsm' evm_llp' evm_lsm']);ylim([0.01 0.1]);set(gca,'yscale','log'); - - %% PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % 1) Digi Demod - d_bm = digimod.demap(Eq_out); - d_dcsm = digimod.demap(yk_dcsm); - d_lvsm = digimod.demap(yk_lvsm); - d_lvlp = digimod.demap(yk_lvlp); - - % 2) BER - dbit = length(d_bm.signal)-length(bitpattern); - - [~,errors_bm,ber_bm,loc] = calc_ber(d_bm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",1); - [~,errors_dcsm,ber_dcsm] = calc_ber(d_dcsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - [~,errors_lvsm,ber_lvsm] = calc_ber(d_lvsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - [~,errors_lvlp,ber_lvlp] = calc_ber(d_lvlp.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0); - - % Display BER - disp(['BER benchmark: ', sprintf('%2E',ber_bm), ' ERRORS: ' ,num2str(sum(errors_bm))]); - disp(['BER dc smooth (A1): ', sprintf('%2E',ber_dcsm), ' ERRORS: ' ,num2str(sum(errors_dcsm))]); - disp(['BER lv smooth (A2): ', sprintf('%2E',ber_lvsm), ' ERRORS: ' ,num2str(sum(errors_lvsm))]); - disp(['BER lv lowpas: ', sprintf('%2E',ber_lvlp), ' ERRORS: ' ,num2str(sum(errors_lvlp))]); - - - %% Generate some Plots - - if 1 - - % SCATTER - col = cbrewer2('Paired',8); - - xax = 1:Eq_out.length; - - figure(3) - sgtitle('') - - subplot(1,3,1) - hold on - eq_decision = digimod.decide_pamlevel(Eq_out); - true_symbols = digimod.decide_pamlevel(digimod_out); - - xindices = 1:Eq_in.length; - errorpos = find(loc~=0)*2; - errorpos(errorpos>length(Eq_in.signal)) = length(Eq_in.signal); - correct = find(loc==0)*2; - correct(correct>length(Eq_in.signal)) = length(Eq_in.signal); - scatter(xindices(correct),Eq_in.signal(correct),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After EQ'); - hold on - scatter(xindices(errorpos),Eq_in.signal(errorpos),6,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision'); - hold off - - xlim([1, xindices(end)]); - ylim([-3 3]); - xlabel('Sampling Index') - ylabel('Amplitude') - a = legend; - a.Location = "best"; - - subplot(1,3,2) - xindices = 1:Eq_out.length; - xax_sec = (1:Eq_out.length) / fsym .* 1e6; - scatter(xax_sec(loc==0),Eq_out.signal(loc==0),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After EQ'); - hold on - scatter(xindices(loc~=0),Eq_out.signal(loc~=0),8,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision'); - hold off - xlim([1, xax(end)]); - ylim([-2 2]); - xlabel('Sampling Index') - ylabel('Amplitude') - legend - a = legend; - a.Location = "best"; - hold off - - subplot(1,3,3) - xindices = 1:yk_lvsm.length; - scatter(xindices(loc==0),yk_lvsm.signal(loc==0),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After A2'); - hold on - scatter(xindices(loc~=0),yk_lvsm.signal(loc~=0),8,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision'); - hold off - xlim([1, xax(end)]); - ylim([-2 2]); - xlabel('Sampling Index') - ylabel('Amplitude') - legend - a = legend; - a.Location = "best"; - hold off - - - end - - if 0 - col = cbrewer2('Paired',8); - - figure(11) - clf - - subplot(2,1,1) - hold on - plot(digimod_out.signal(4150:4175),'DisplayName','Tx','Color',col(1,:),'LineWidth',3); - plot(Eq_out.signal(4150:4175),'DisplayName','Rx after EQ','Color',col(6,:),'LineWidth',1); - title('Modulated Sequence Zoom'); - legend - hold off - subplot(2,1,2) - hold on - stem(d_bm.signal(4150:4175,1),'DisplayName','Tx','Color',col(1,:),'LineStyle','-','LineWidth',5) - stem(bitpattern(4150:4175,1)','DisplayName','Rx','Color',col(6,:),'LineStyle','--','LineWidth',2) - title('Bitpattern Tx - Rx'); - legend - hold off - - end - -end - diff --git a/projects/IMDD_base_system/submit_simulations.m b/projects/IMDD_base_system/submit_simulations.m new file mode 100644 index 0000000..bfc68f1 --- /dev/null +++ b/projects/IMDD_base_system/submit_simulations.m @@ -0,0 +1,74 @@ +function wh = submit_simulations(wh,db,options) + +arguments + wh + db + options.parallel = 1; + options.simulation_mode = 1; +end + +%%% 2) SUBMIT SIMULATION +% Initialize job results +if options.parallel + if isempty(gcp('nocreate')) + parpool; + end + results = parallel.FevalFuture.empty(); +else + results = []; +end + + +lin_idx = 1; +for lin_idx = 1:wh.getLastLinIndice + optionalVars = struct(); + if ~isempty(wh.getDimension) + % Build the optionalVars struct + [parametervalues,parameternames]=wh.getPhysIndicesByLinIndex(lin_idx); + for pidx = 1:numel(parameternames) + optionalVars.(parameternames{pidx}) = parametervalues{pidx}; + end + end + + %%% SIMULATION HERE + if options.parallel + + numOutputs = 1; + results(lin_idx) = parfeval(@imdd_model, numOutputs, options.simulation_mode, db, optionalVars); + + else + + finalresults{lin_idx} = imdd_model(options.simulation_mode,db,optionalVars); + wh.addValueToStorageByLinIdx(finalresults{lin_idx}, 'ber', lin_idx); + + end +end + + + +if options.parallel + + %%% 4) Setup waitbar + h = waitbar(0, 'Processing Simulations...'); + % Helper function to compute progress + updateWaitbar = @(~) waitbar(mean(arrayfun(@(f) strcmp(f.State, 'finished'), results)), h); + + fprintf('Fetching results... \n'); + + % Update the waitbar after each simulation + updateWaitbarFutures = afterEach(results, updateWaitbar, 0); + + % Close the waitbar after all simulations complete + afterAll(updateWaitbarFutures, @(~) delete(h), 0); + + %%% 7) Fetch final results after all computations + fetchOutputs(results); + + for ridx = 1:length(results) + wh.addValueToStorageByLinIdx(results(ridx).OutputArguments{1}, 'ber', ridx); + end + +end + + +end \ No newline at end of file diff --git a/projects/IMDD_base_system/tx_simulation.m b/projects/IMDD_base_system/tx_simulation.m new file mode 100644 index 0000000..926c60c --- /dev/null +++ b/projects/IMDD_base_system/tx_simulation.m @@ -0,0 +1,31 @@ + + + Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha); + + [Digi_sig,Symbols,Tx_bits] = PAMsource(... + "fsym",fsym,"M",M,"order",19,"useprbs",1,... + "fs_out",fdac,... + "applyclipping",0,"clipfactor",1.5,... + "applypulseform",apply_pulsef,"pulseformer",Pform,... + "randkey",random_key,... + "db_precode",db_precode,"db_encode",db_encode,... + "mrds_code",0,"mrds_blocklength",512).process(); + + Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1); + + %%%%% AWG + % El_sig = M8199A("kover",kover).process(Digi_sig); + El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig); + % El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0); + % El_sig = El_sig.setPower(0,"dBm"); + + %%%%% Low-pass el. components %%%%%% + El_sig = Filter('filtdegree',4,"f_cutoff",tx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig); + + %%%%% Electrical Driver Amplifier %%%%%% + El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig); + El_sig = El_sig.normalize("mode","oneone"); + + %%%%% MODULATE E/O CONVERSION %%%%%% + [Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1).process(El_sig); + diff --git a/projects/MPI_August/auswertung/M_4_datarate_224_sir_35_laser_linewidth_1000000_pn_key_1_rop_0.mat b/projects/MPI_August/auswertung/M_4_datarate_224_sir_35_laser_linewidth_1000000_pn_key_1_rop_0.mat new file mode 100644 index 0000000..bf2c100 Binary files /dev/null and b/projects/MPI_August/auswertung/M_4_datarate_224_sir_35_laser_linewidth_1000000_pn_key_1_rop_0.mat differ diff --git a/python_version/amp_mode.py b/python_version/amp_mode.py deleted file mode 100644 index 65da429..0000000 --- a/python_version/amp_mode.py +++ /dev/null @@ -1,7 +0,0 @@ -from enum import IntEnum - -class amp_mode(IntEnum): - ideal_no_noise = 1 - edfa_increase_nase = 2 - edfa_replace_nase = 3 - # edfa_set_osnr = 4 TODO: implement mode to achieve desired OSNR \ No newline at end of file diff --git a/python_version/ampclass.py b/python_version/ampclass.py deleted file mode 100644 index 6d1789b..0000000 --- a/python_version/ampclass.py +++ /dev/null @@ -1,86 +0,0 @@ -import numpy as np -import scipy.constants as Constant -import amp_mode -import gain_mode -import nase_mode - -class Amplifier: - def __init__(self, options=None): - self.amp_mode = options.amp_mode if options and hasattr(options, 'amp_mode') else amp_mode.ideal_no_noise - self.gain_mode = options.gain_mode if options and hasattr(options, 'gain_mode') else gain_mode.output_power - self.nase_mode = options.nase_mode if options and hasattr(options, 'nase_mode') else nase_mode.pass_ase - self.amplification_db = options.amplification_db if options and hasattr(options, 'amplification_db') else 0 - self.noifig = options.noifig if options and hasattr(options, 'noifig') else 0 - self.fsimu = options.fsimu if options and hasattr(options, 'fsimu') else None - - def process(self, signalclass_in): - signalclass_in = self.process_(signalclass_in) - lbdesc = 'Amp ' - signalclass_in = signalclass_in.logbookentry(lbdesc) - signalclass_out = signalclass_in - return signalclass_out - - def process_(self, X_in): - a_lin = self.calculateGain(X_in.signal) - X_in.signal = a_lin * X_in.signal - - if isinstance(X_in, Opticalsignal): - if self.amp_mode == amp_mode.ideal_no_noise: - X_in.nase = self.onlyAmplifyAse(X_in.nase, a_lin) - elif self.amp_mode == amp_mode.edfa_increase_nase: - X_in.nase = self.increaseAse(X_in.nase, a_lin, self.noifig, X_in.lambda_) - elif self.amp_mode == amp_mode.edfa_replace_nase: - X_in.nase = self.replaceAse(X_in.nase, a_lin, self.noifig, X_in.lambda_) - - if self.nase_mode == nase_mode.generate_ase: - nase = X_in.nase - fs = X_in.fs - dimension = X_in.signal.shape - nase_numeric = self.generateAseNoise(nase, fs, dimension) - X_in.signal, osnr = self.applyAseToSignal(X_in.signal, nase_numeric) - X_in.nase = 0 - elif self.nase_mode == nase_mode.pass_ase: - X_in.nase = X_in.nase - - X_out = X_in - return X_out - - def calculateGain(self, xin): - if self.gain_mode == gain_mode.output_power: - pow_in = np.mean(np.abs(xin) ** 2) - pow_out = 10 ** (self.amplification_db / 10 - 3) - a_lin = np.sqrt(pow_out / pow_in) - elif self.gain_mode == gain_mode.gain: - a_lin = 10 ** (self.amplification_db / 20) - return a_lin - - def onlyAmplifyAse(self, nase_old, a_lin): - nase_amped = a_lin ** 2 * nase_old - return nase_amped - - def calculateAseFromThisAmp(self, a_lin, noisefig, lambda_): - h = Constant.Planck - c = Constant.speed_of_light - nase_new = 0.5 * 10 ** (noisefig / 10) * h * c / lambda_ * (a_lin ** 2 - 1) - return nase_new - - def increaseAse(self, nase_old, a_lin, noisefig, lambda_): - nase_fromThisAmp = self.calculateAseFromThisAmp(a_lin, noisefig, lambda_) - nase_old = a_lin ** 2 * nase_old - ase_increased = nase_old + nase_fromThisAmp - return ase_increased - - def replaceAse(self, nase_old, a_lin, noisefig, lambda_): - nase_fromThisAmp = self.calculateAseFromThisAmp(a_lin, noisefig, lambda_) - nase_new = nase_fromThisAmp - return nase_new - - def generateAseNoise(self, nase, fs, dimension): - nase_numeric = (np.random.randn(*dimension) + 1j * np.random.randn(*dimension)) * np.sqrt(nase / 2 * fs) - return nase_numeric - - def applyAseToSignal(self, opticalsignal, nase_numeric): - noisy_sig = opticalsignal + nase_numeric - osnr = pow(10 * np.log10(np.mean(np.abs(opticalsignal) ** 2) / np.mean(np.abs(nase_numeric) ** 2))) - print(osnr) - return noisy_sig, osnr diff --git a/python_version/gain_mode.py b/python_version/gain_mode.py deleted file mode 100644 index 6fa928d..0000000 --- a/python_version/gain_mode.py +++ /dev/null @@ -1,5 +0,0 @@ -from enum import IntEnum - -class gain_mode(IntEnum): - gain = 1 - output_power = 2 \ No newline at end of file diff --git a/python_version/nase_mode.py b/python_version/nase_mode.py deleted file mode 100644 index f88e2f7..0000000 --- a/python_version/nase_mode.py +++ /dev/null @@ -1,5 +0,0 @@ -from enum import IntEnum - -class nase_mode(IntEnum): - generate_ase = 1 - pass_ase = 2 \ No newline at end of file diff --git a/python_version/python_trial.py b/python_version/python_trial.py deleted file mode 100644 index 26a5866..0000000 --- a/python_version/python_trial.py +++ /dev/null @@ -1,3 +0,0 @@ -from ampclass import Amplifier - -a = Amplifier() diff --git a/test/duobinary_emulation_minimal_example.m b/test/duobinary_emulation_minimal_example.m new file mode 100644 index 0000000..c390d3f --- /dev/null +++ b/test/duobinary_emulation_minimal_example.m @@ -0,0 +1,75 @@ +useprbs = 1; +M = 4; +randkey = 1; +datarate = 224e9; +fsym = round(datarate / log2(M)) ; + +db_pre = 1; + +Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",0.05); + +[d,Symbols,Bits] = PAMsource(... + "fsym",fsym,"M",M,"order",17,"useprbs",1,... + "fs_out",fsym,... + "applyclipping",0,"clipfactor",1.5,... + "applypulseform",0,"pulseformer",Pform,... + "randkey",1,... + "db_precode",db_pre,"db_encode",0,... + "mrds_code",0,"mrds_blocklength",512).process(); + +%%%CHANNEL + +% s = RandStream('twister','Seed',2); +% start = 10000; +% burstwidth = 100; +% d_burst = d; +% for pos = start:start+burstwidth +% lvls = 1.5 .* PAMmapper(M,0).levels / rms(PAMmapper(M,0).levels); +% d_burst.signal(pos) = d.signal(pos)+randn(s,1,1); +% end + +d_resample = d.resample("fs_out",2.*fsym); + +eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",1024,"mu_dd",0.0004,"mu_tr",0,"order",25,"sps",2,"decide",1); +d_eq = eq_ffe.process(d_resample,Symbols); + +% s = RandStream('twister','Seed',2); +% start = 10000; +% burstwidth = 100; +% d_burst = d_eq; +% for pos = start:start+burstwidth +% lvls = 1.5 .* PAMmapper(M,0).levels / rms(PAMmapper(M,0).levels); +% d_burst.signal(pos) = d_eq.signal(pos)+randn(s,1,1); +% end +% +% d_burst = PAMmapper(M,0).decide_pamlevel(d_burst); + +if db_pre + % Entschiedene Symbole codieren: d_DB(n) = d(n) + d(n-1) (im Fall von PAM4 7 level [0 1 2 3 4 5 6]) + d_db = Duobinary().encode(d); + + % Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4 + d_dec = Duobinary().decode(d_db); +else + d_dec = d_burst; +end + +% Vergleichen von b(n) und d_dec(n) +Rx_bits = PAMmapper(M,0).demap(d_dec); + +Tx_bits = Bits; + +[~,error_num,ber,error_pos] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1); + +disp(['BER: ',sprintf('%.1E',ber),' - - PAM-',num2str(M)]); + +figure(200) +clf +hold on +idxs = start-10:start+burstwidth+10; +scatter(idxs,d.signal(idxs),'DisplayName',['Orig Signal'],'Marker','o'); +scatter(idxs,d_burst.signal(idxs),'DisplayName',['Error Signal'],'Marker','x'); +scatter(idxs,d_dec.signal(idxs),'DisplayName',['EQ Signal'],'Marker','x'); +yline(PAMmapper(M,0).thresholds,'HandleVisibility','off'); +legend +ylim([-2 2]) \ No newline at end of file diff --git a/test/duobinary_minimal_example.m b/test/duobinary_minimal_example.m index bcd2de7..79e9f86 100644 --- a/test/duobinary_minimal_example.m +++ b/test/duobinary_minimal_example.m @@ -1,43 +1,55 @@ useprbs = 1; -M = 6; +M = 4; randkey = 1; datarate = 448e9; fsym = round(datarate / log2(M)) ; %%%%% PRBS Generation in correct shape for Modulation Format %%%%%% -O = 17; %order of prbs +O = 15; %O of prbs N = 2^(O); %length of prbs [~,seed] = prbs(O,1); %initialize first seed of prbs bitpattern=[]; -if useprbs - for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); - end -else - s = RandStream('twister','Seed',randkey); - for i = 1:log2(M) - bitpattern(:,i) = randi(s,[0 1], N, 1); - end -end +state = struct(); + +para = struct(); if M == 6 - bitpattern = reshape(bitpattern,[],1); - bitpattern = bitpattern(1:end-mod(length(bitpattern),5)); + para.bl = 2^(O-2); + para.dimension = 5; +else + para.bl = 2^(O-1); + para.dimension = log2(M); %2.5bits/sym -> 2 bit/sym end +para.rand = 0; + +para.order = floor(O / log2(M)); +para.skip =0; +para.bruijn = 0; +para.reset_prms = 0; +para.method = 1; + +data_in = []; +global loop; +loop = 0; +[data_out,state_] = prms(data_in, state, para); +loop = 1; +[data_out,state_out] = prms(data_in, state_, para); +bitpattern = data_out'; + Tx_bits = Informationsignal(bitpattern); Symbols_tx = PAMmapper(M,0).map(Tx_bits); Symbols_tx.fs = fsym; -Symbols = Duobinary().precode(Symbols_tx); +Symbols1 = Duobinary().precode(Symbols_tx); -Symbols = Duobinary().encode(Symbols); +Symbols2 = Duobinary().encode(Symbols1); -Symbols = Duobinary().decode(Symbols); +Symbols3 = Duobinary().decode(Symbols2); -Rx_bits = PAMmapper(M,0).demap(Symbols); +Rx_bits = PAMmapper(M,0).demap(Symbols3); [~,error_num,ber,error_pos] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1); diff --git a/test/exampleFunction.m b/test/exampleFunction.m new file mode 100644 index 0000000..4830167 --- /dev/null +++ b/test/exampleFunction.m @@ -0,0 +1,32 @@ +function output = exampleFunction(varargin) + + % Default values for optional variables + var_1 = 1; + var_2 = 2; + var_4 = 10; % Default value for var4 + var_5 = 20; % Default value for var5 + var_6 = 30; % Default value for var6 + var_7 = 40; % Default value for var7 + var_8 = 50; % Default value for var8 + var_9 = 60; % Default value for var9 + var_10 = 70; % Default value for var10 + + % Parse optional input arguments + if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n",fields{i},var_s.(fields{i})) + end + else + error('Optional variables should be passed as a struct.'); + end + end + + output = var_4+var_10+var_9+var_8+var_1+var_2; + + +end + diff --git a/test/run_examplefcn.m b/test/run_examplefcn.m new file mode 100644 index 0000000..f00cbcd --- /dev/null +++ b/test/run_examplefcn.m @@ -0,0 +1,100 @@ +% Define ranges for variables to iterate over +var1_range = [1, 2, 3, 4, 6]; +var2_range = [10, 20]; +var3_range = [100, 200]; + +% Prepare the parallel pool +if isempty(gcp('nocreate')) + parpool; % Start a parallel pool if not already running +end + +% Array to hold measurement futures +measurements = parallel.FevalFuture.empty(); + +% Array to hold DSP results +dsp_results = parallel.Future.empty(); + +% Nested for loops for all parameter combinations +lin_idx = 1; +for v1 = var1_range + for v2 = var2_range + for v3 = var3_range + % Construct the struct of optional variables for this iteration + optionalVars = struct('var_4', v1, 'var_5', v2, 'var_6', v3); + + % Submit the measurement function to the parallel pool + measurements(lin_idx) = parfeval(@measurement, 1, optionalVars); + + % Link DSP function to run after measurement completes + dsp_results(lin_idx) = afterEach(measurements(lin_idx), @(output) rundsp(output, optionalVars), 1); + + lin_idx = lin_idx + 1; % Increment linear index + end + end +end + +% Fetch and display DSP results +final_results = cell(numel(dsp_results), 1); +for i = 1:numel(dsp_results) + fprintf('Fetching DSP result for job %d...\n', i); + final_results{i} = fetchOutputs(dsp_results(i)); % Fetch each DSP result individually +end + +fprintf('All DSP evaluations completed.\n'); +disp('Final Results:'); +disp(final_results); + +% --- Measurement Function --- +function output = measurement(varargin) + + % Default values for optional variables + var_1 = 1; + var_2 = 2; + var_4 = 10; % Default value for var4 + var_5 = 20; % Default value for var5 + var_6 = 30; % Default value for var6 + var_7 = 40; % Default value for var7 + var_8 = 50; % Default value for var8 + var_9 = 60; % Default value for var9 + var_10 = 70; % Default value for var10 + + % Parse optional input arguments + if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + end + else + error('Optional variables should be passed as a struct.'); + end + end + + % Simulate output with a random delay + output = randi(5); % Random result + pause(output); % Simulate processing time +end + +% --- DSP Function --- +function output = rundsp(measurement_output, varargin) + + % Parse optional input arguments + if ~isempty(varargin) + var_s = varargin{1}; + if isstruct(var_s) + fields = fieldnames(var_s); + for i = 1:numel(fields) + eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); + fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); + end + else + error('Optional variables should be passed as a struct.'); + end + end + + % Simulate DSP processing based on measurement output + output = measurement_output + 10; % Add 10 to measurement output + pause(measurement_output); % Simulate DSP processing time +end