Hi folks,
I noticed that in OXSA, they don’t use the naive fft and ifft to convert between FID and spectrum. Instead, they have specFft and specInvFft. Those two functions are not long, so I post the code below.
function [spec] = specFft(fid,dim)
% FFT for spectroscopy. Converts fid --> spectrum.
%
% Accounts correctly for the 0.5x weighting for the t=0 FID point arising
% from the one-sided definition of the Fourier Transform relations in
% spectroscopy.
%
% Optional parameter: dim is the dimension to be FFT'd. Default is 1.
%
% EXAMPLE:
% zz=randn(2048,1)+1i*randn(2048,1);maxdiff(zz,specFft(specInvFft(zz)))
% OR
% zz=randn(2048,128)+1i*randn(2048,128);maxdiff(zz,specFft(specInvFft(zz)));maxdiff(zz,specFft(specInvFft(zz,2),2))
if nargin<2
dim = 1;
end
perm = [dim 1:(dim-1) (dim+1):numel(size(fid))];
% Re-use variable name "spec" to economise on RAM.
spec = permute(fid,perm);
% t=0 point is treated differently by convention for a FID
spec(1,:) = spec(1,:) * 0.5;
spec = ipermute(fftshift(fft(spec,[],1),1)/size(spec,1),perm);
function [fid] = specInvFft(spec,dim)
% Inverse FFT for spectroscopy. Converts spectrum --> fid.
%
% Accounts correctly for the 0.5x weighting for the t=0 FID point arising
% from the one-sided definition of the Fourier Transform relations in
% spectroscopy.
%
% Optional parameter: dim is the dimension to be FFT'd. Default is 1.
%
% EXAMPLE:
% zz=randn(2048,1)+1i*randn(2048,1);maxdiff(zz,specFft(specInvFft(zz)))
% OR
% zz=randn(2048,128)+1i*randn(2048,128);maxdiff(zz,specFft(specInvFft(zz)));maxdiff(zz,specFft(specInvFft(zz,2),2))
if nargin<2
dim = 1;
end
fid = ifft(fftshift(spec,dim),[],dim)*size(spec,dim);
perm = [dim 1:(dim-1) (dim+1):numel(size(fid))];
% Re-use variable name "fid" to economise on RAM.
fid = permute(fid,perm);
% t=0 point is treated differently by convention for a FID
fid(1,:) = 2*fid(1,:);
fid = ipermute(fid,perm);
I think these two functions basically do two things different from the naive fft and ifft.
- When converting FID to spectrum, it first multiplies the first point in FID by 0.5
- It divides the result of
fftshift(fft(fid))bynumel(fid)(supposefidis a vector)
I understand that, the second difference only makes the result scale by numel(fid) or 1/numel(fid) My question is, why multiplying the first point in FID by 0.5? What’s the consequence if I simply use the naive fft and ifft? Or in other words, in practice, does it make a significant difference?
(Plus, I think in specInvFft, the line fid = ifft(fftshift(spec,dim),[],dim)*size(spec,dim); should use ifftshift instead of fftshift, in case numel(fid) is an odd number.)