WIP büro
This commit is contained in:
80
Classes/03_receive/Photodiode.m
Normal file
80
Classes/03_receive/Photodiode.m
Normal file
@@ -0,0 +1,80 @@
|
||||
classdef Photodiode
|
||||
%PGOTODIODE Summary of this class goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
properties
|
||||
fsimu
|
||||
responsivity
|
||||
dark_current
|
||||
temperature
|
||||
|
||||
end
|
||||
|
||||
methods
|
||||
function obj = Photodiode(options)
|
||||
%PHOTODIODE Construct an instance of this class
|
||||
% Detailed explanation goes here
|
||||
arguments
|
||||
options.fsimu
|
||||
options.responsivity = 1;
|
||||
options.dark_current = 0;
|
||||
options.temperature = 20;
|
||||
end
|
||||
|
||||
obj.fsimu = options.fsimu;
|
||||
obj.responsivity = options.responsivity;
|
||||
obj.dark_current = options.dark_current;
|
||||
obj.temperature = options.temperature;
|
||||
|
||||
end
|
||||
|
||||
function signalclass_out = process(obj,signalclass_in)
|
||||
|
||||
% actual processing of the signal (steps 1. - 3.)
|
||||
signalclass_in.signal = obj.process_(signalclass_in.signal);
|
||||
|
||||
% cast the inform. signal to electrical signal
|
||||
[signalclass_in, nase, lambda] = Electricalsignal(signalclass_in,"fs",obj.fsimu,"logbook",signalclass_in.logbook);
|
||||
|
||||
% append to logbook
|
||||
lbdesc = ['Photo Diode '];
|
||||
signalclass_in = signalclass_in.logbookentry(lbdesc);
|
||||
|
||||
% write to output
|
||||
signalclass_out = signalclass_in;
|
||||
|
||||
end
|
||||
|
||||
function yout = process_(obj,xin)
|
||||
%METHOD1 Summary of this method goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
k = Constant.Boltzmann;
|
||||
T = obj.temperature + 273.15 ; %celsius + 273 = kelvin
|
||||
R = 50; %resistance of phdiode (50ohm is typical value)
|
||||
|
||||
% Magnitude squared detection
|
||||
yout = sum( abs(xin) .^2*obj.responsivity, 2 ) ;
|
||||
|
||||
% Shot Noise
|
||||
shot_noise = sqrt(k * obj.fsimu .* yout) .* randn(size(yout,1),1);
|
||||
|
||||
yout = yout + shot_noise;
|
||||
|
||||
% Thermal Noise
|
||||
therm_current_psd = (2 * k * T / R ) ; %squared
|
||||
|
||||
Bw = obj.fsimu; %is this correct? shouldnt it be the bandwidth of the actual component? e.g. 70GHz?
|
||||
therm_noise_pow = therm_current_psd * 2 * Bw; %squared
|
||||
|
||||
therm_noise = sqrt(therm_noise_pow) .* randn(size(yout,1),1);
|
||||
|
||||
yout = yout + therm_noise;
|
||||
|
||||
% Dark Current
|
||||
yout = yout + obj.dark_current ;
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
210
Classes/03_receive/Scope.m
Normal file
210
Classes/03_receive/Scope.m
Normal file
@@ -0,0 +1,210 @@
|
||||
classdef Scope
|
||||
%SCOPE Summary of this class goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
properties
|
||||
fsimu
|
||||
fadc
|
||||
adcresolution
|
||||
quantbuffer
|
||||
|
||||
rand_samplingdelay %on or off
|
||||
samplingdelay %specifiy a sampling delay
|
||||
|
||||
freq_offset %offset of the sampler
|
||||
samp_jitter %include jitter
|
||||
|
||||
fixed_delay %fix the delay of the filter or use minimal delay for kausal system
|
||||
delay %specify a fixed delay of the filter
|
||||
|
||||
filtertype
|
||||
lpf_bw
|
||||
|
||||
%during construction
|
||||
|
||||
%during process
|
||||
Nout
|
||||
end
|
||||
|
||||
methods
|
||||
function obj = Scope(options)
|
||||
%SCOPE Construct an instance of this class
|
||||
% Detailed explanation goes here
|
||||
arguments
|
||||
options.fsimu
|
||||
options.fadc
|
||||
options.adcresolution
|
||||
options.quantbuffer
|
||||
|
||||
options.rand_samplingdelay = 0;
|
||||
options.samplingdelay = 0;
|
||||
|
||||
options.freq_offset = 0;
|
||||
options.samp_jitter = 0;
|
||||
|
||||
options.fixed_delay = 0;
|
||||
options.delay = 0;
|
||||
|
||||
options.filtertype = filtertypes.bessel_bilin;
|
||||
options.lpf_bw = 120e9;
|
||||
end
|
||||
|
||||
obj.fsimu = options.fsimu;
|
||||
obj.fadc = options.fadc;
|
||||
obj.adcresolution = options.adcresolution;
|
||||
obj.quantbuffer = options.quantbuffer;
|
||||
|
||||
obj.rand_samplingdelay = options.rand_samplingdelay; % use a randomized sample delay INSTEAD of samplingdelay
|
||||
obj.samplingdelay = options.samplingdelay; %specifiy a sampling delay
|
||||
|
||||
obj.freq_offset = options.freq_offset; %offset of the sampler
|
||||
obj.samp_jitter = options.samp_jitter; %include jitter in [s]
|
||||
|
||||
obj.fixed_delay = options.fixed_delay; %fix the delay of the filter or use minimal delay for kausal system
|
||||
obj.delay = options.delay; %specify a fixed delay of the filter
|
||||
|
||||
obj.filtertype = options.filtertype;
|
||||
obj.lpf_bw = options.lpf_bw;
|
||||
|
||||
end
|
||||
|
||||
function signalclass_out = process(obj,signalclass_in)
|
||||
|
||||
% apply LPF
|
||||
lpf = Filter('filtdegree',3,"f_cutoff",obj.lpf_bw,"fsamp",obj.fsimu,"filterType",obj.filtertype);
|
||||
signalclass_in = lpf.process(signalclass_in);
|
||||
|
||||
% actual processing of the signal
|
||||
signalclass_in.signal = obj.process_(signalclass_in.signal);
|
||||
|
||||
% append to logbook
|
||||
lbdesc = ['Scope '];
|
||||
signalclass_in = signalclass_in.logbookentry(lbdesc);
|
||||
|
||||
% write to output
|
||||
signalclass_out = signalclass_in;
|
||||
|
||||
end
|
||||
|
||||
function yout = process_(obj,xin)
|
||||
%METHOD1 Summary of this method goes here
|
||||
% Detailed explanation goes here
|
||||
|
||||
% sample signal
|
||||
% TODO: implement and test the delays. Also look for delay of
|
||||
% lpf filter
|
||||
%yout = obj.sampleSignal(xin);
|
||||
yout = resample(xin,obj.fadc,obj.fsimu);
|
||||
|
||||
% quantize signal
|
||||
yout = obj.quantize(yout);
|
||||
|
||||
|
||||
end
|
||||
|
||||
function jitvec = buildSamplingJitterVector(obj)
|
||||
% Generation of sampling jitter vector for real part of signal
|
||||
jitvec = obj.samp_jitter*randn(obj.Nout,1) ;
|
||||
|
||||
% Avoid exceding the simulation block edges relentlessly!
|
||||
jitvec(1) = abs(jitvec(1)) ;
|
||||
jitvec(end) = -abs(jitvec(end)) ;
|
||||
|
||||
end
|
||||
|
||||
function sampout = sampleSignal(obj,xin)
|
||||
|
||||
% Initialization sampler and output signal in case of 4real
|
||||
|
||||
Tout = 1 / obj.fadc; % output signal sample period [sec]
|
||||
|
||||
Tsig = length(xin) / obj.fsimu ; % simulation block period [sec]
|
||||
|
||||
if obj.rand_samplingdelay == 1
|
||||
obj.samplingdelay = Tout*rand ;
|
||||
end
|
||||
|
||||
%get number of delayed samples
|
||||
Ndelay = floor(obj.samplingdelay*obj.fsimu) ;
|
||||
|
||||
%get fractional sample delay
|
||||
fracdelay = obj.samplingdelay - Ndelay/obj.fsimu ;
|
||||
|
||||
%calc number of samples after down-sampling no offset
|
||||
obj.Nout = ceil((Tsig - fracdelay)*obj.fadc) ;
|
||||
|
||||
%build a jitter vector
|
||||
jitvec = obj.buildSamplingJitterVector();
|
||||
|
||||
% Create the index vector of the sampling instances for the real and imaginary part
|
||||
inx_re = ( (0: Tout : (obj.Nout-1) / obj.fadc)' + jitvec ) * obj.fsimu + 1 ;
|
||||
|
||||
% Create the vector of the relative location of each sample between
|
||||
% to neighboring "Analog" samples for the real and imaginary part
|
||||
val_re = mod(inx_re,1) ;
|
||||
|
||||
% Shift the signal
|
||||
xin = circshift(xin, [0 - Ndelay]) ;
|
||||
|
||||
% Sample the signal using linear interpolation
|
||||
sampout = xin(floor(inx_re)) .* (1 - val_re) + xin(ceil(inx_re)) .* val_re ;
|
||||
|
||||
sampout2 = resample(xin,obj.fadc,obj.fsimu);
|
||||
|
||||
end
|
||||
|
||||
function quantout = quantize(obj,xin)
|
||||
|
||||
quant_steps = round(2^obj.adcresolution) + rem(round(2^obj.adcresolution),2);
|
||||
|
||||
if quant_steps > 0
|
||||
|
||||
index = round(0.1*length(xin)); %sioe 2022: short blocksize resulted in error -> now 10%-90% of length are evaluated
|
||||
|
||||
max_re = max(real(xin(index:end-index)))*(1+obj.quantbuffer/2); % adaptations in the indices
|
||||
min_re = min(real(xin(index:end-index)))*(1-obj.quantbuffer/2); %(1+para.max/2);
|
||||
|
||||
range_re = max_re-min_re;
|
||||
|
||||
max_im = max(imag(xin))*(1+obj.quantbuffer/2);
|
||||
min_im = min(imag(xin))*(1+obj.quantbuffer/2);
|
||||
|
||||
range_im = max_im-min_im;
|
||||
|
||||
if isreal(xin)
|
||||
% shift signal and clip to quantizer intervall
|
||||
xin = min(max(xin-min_re,0),range_re);
|
||||
|
||||
% quantize signal
|
||||
xin = round((quant_steps-1)/range_re*xin);
|
||||
|
||||
% scale and shift back
|
||||
quantout = xin*range_re/(quant_steps-1) +min_re;
|
||||
|
||||
else
|
||||
|
||||
% shift signal and clip to quantizer intervall
|
||||
xin_re = min(max(real(xin)-min_re,0),range_re);
|
||||
xin_im = min(max(imag(xin)-min_im,0),range_im);
|
||||
|
||||
% quantize signal
|
||||
|
||||
% quantize signal and shift back signal
|
||||
xin_re = round((quant_steps-1)/range_re*xin_re);
|
||||
xin_im = round((quant_steps-1)/range_im*xin_im);
|
||||
|
||||
% scale and shift back
|
||||
quant_out_re = xin_re*range_re/(quant_steps-1) + min_re;
|
||||
quant_out_im = xin_im*range_im/(quant_steps-1) + min_im;
|
||||
quantout = quant_out_re + 1i * quant_out_im;
|
||||
|
||||
end
|
||||
else
|
||||
quantout = xin;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user