Files
Silas Oettinghaus ed17953407 Update April
2024-04-19 10:31:36 +02:00

228 lines
7.3 KiB
Matlab

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
lpf_active
filtertype
lpf_bw
H_lpf
block_dc
%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.lpf_active = 0;
options.filtertype = filtertypes.bessel_bilin;
options.lpf_bw = 120e9;
options.H_lpf;
options.block_dc = 1;
end
fn = fieldnames(options);
for n = 1:numel(fn)
try
obj.(fn{n}) = options.(fn{n});
end
end
end
function signalclass_out = process(obj,signalclass_in)
% actual processing of the signal
signalclass_in.signal = obj.process_(signalclass_in.signal);
signalclass_in.fs = obj.fadc;
% apply LPF
% 4. Apply LPF on the signal
assert (signalclass_in.fs == obj.H_lpf.fs)
if obj.lpf_active
if isa(obj.H_lpf,'Filter')
%4.A) user already specified a complete filter class when
% initializing the AWG module
signalclass_in = obj.H_lpf.process(signalclass_in);
else
%4.B) just use a standard filter
obj.H_lpf = Filter('filtdegree',3,"f_cutoff",obj.lpf_bw,"fsamp",obj.fsimu,"filterType",obj.filtertype);
signalclass_in = obj.H_lpf.process(signalclass_in);
end
end
% cast the electrical signal to information signal
signalclass_in = Informationsignal(signalclass_in,"fs",obj.fadc,"logbook",signalclass_in.logbook);
% 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.
% resample
yout = resample(xin,obj.fadc,obj.fsimu);
% quantize signal
yout = obj.quantize(yout);
if obj.block_dc
yout = yout-mean(yout,1);
end
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