-
Notifications
You must be signed in to change notification settings - Fork 0
/
field_mod_sim.m
106 lines (87 loc) · 2.88 KB
/
field_mod_sim.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
function yModInPhase = field_mod_sim(x, y, modAmp, harmonic)
%FIELD_MOD_SIM simulates the distortions of lock-in detection on a signal.
%
% yModInPhase = FIELD_MOD_SIM(x, y, modAmp);
% yModInPhase = FIELD_MOD_SIM(x, y, modAmp, harmonic);
%
% Computes the effect of x-axis modulation with amplitude ModAmp and
% n-th harmonic detection on a signal (x,y). This code implements the
% psuedo-modulation approach from:
%
% Hyde, J. S., et al. Applied Magnetic Resonance 1, 483-496 (1990)
%
% INPUT:
% x - x-axis data vector, must be uniformliy spaced
% y - signal vector
% modAmp - peak-to-peak modulation amplitude [same units as x]
% harmonic - harmonic (0, 1, 2, ...); default is 1
%
% OUTPUT:
% - yModInPhase: in-phase component of pseudo-modulated spectrum
%
% If no output variable is given, field_mod_sim plots the
% original and the modulated spectrum.
%
% Example:
%
% x = linspace(300,400,1001);
% y = lorentzian(x,342,4);
% field_mod_sim(x,y,20);
%
% $Author: Sam Schott, University of Cambridge <ss2151@cam.ac.uk>$
import esr_analyses.*
import esr_analyses.utils.*
%% input checks
if (nargin == 0)
help(mfilename)
return
end
Display = (nargout == 0);
if (nargin < 3) || (nargin > 4), error('Wrong number of input arguments!'); end
if (nargout < 0), error('Not enough output arguments.'); end
if (nargout > 1), error('Too many output arguments.'); end
if (nargin < 4)
harmonic = 1;
end
if numel(harmonic) ~= 1 || (harmonic < 0) || ~isreal(harmonic) || mod(harmonic, 1)
error('Harmonic must be a positive integer (1, 2, 3, etc)!');
end
if (modAmp <= 0)
error('Modulation amplitude (3rd argument) must be positive.');
end
n = length(x);
if length(y) ~= n
error('x and y must have the same length!');
end
sizey = size(y);
if all(sizey ~= 1)
error('y must be a row or column vector.');
end
isRowVector = (sizey(1) == 1);
y = y(:);
%% calculate convolution
dx = x(2) - x(1); % get spacing of x-axis, assuming uniform spacing
Ampl = modAmp / 2 / dx; % modulation amplitude in multiples of x-axis steps
NN = n; % zero padding length for fft
ffty = fft(y, NN); % fourier transform signal
ffty(ceil(NN / 2) + 1:end) = 0; % truncate upper half with zeros
% multiply with modulation kernel and fourier transform back
S = (0:NN - 1)' / NN;
yMod = ifft(ffty .* besselj(harmonic, 2 * pi * Ampl * S));
yMod = yMod(1:n); % truncate data (reverse zero padding)
yMod = (1i) ^ harmonic * yMod; % swap real and imaginary parts depending on harmonic
if isRowVector
yMod = yMod';
end
yModInPhase = real(yMod); % get in-phase data from real part
% plot if output variable is specified
if (Display)
subplot(3, 1, 1);
plot(x, y);
title('Original spectrum');
subplot(3, 1, [ 2, 3 ]);
plot(x, yModInPhase);
xlabel('Magnetic field [G]');
title(sprintf('Modulated spectrum, harmonic %d, modulation amplitude %g G', harmonic, modAmp));
end
end