# How to calibrate a signal with respect to frequency

I have recordings from accelerometers (non-flat response with respect to frequency) and I'd like to convert my voltage time series into acceleration values. Is there a standard method for doing this?

My proposal to achieve this is:

1. Break the signal into equally spaced segments overlapping with 50%.
2. Apply a fft (with appropriate window) to each segment and apply the calibration values to each frequency.
3. Convert the segment back into a time series by applying an ifft and reversing the window transform. We not have calibrated segments of the time series, although they are likely disjoint between window segments.
4. Apply a triangle window to all overlapping segments and add them into a single time series. The triangle window should result in smooth transitions between window segments, resulting in a continuous, calibrated time series.

Are there any problems with this approach? The window choice is dependent on use case. Are there other approaches to achieve the same goal?

Potentially a lot of problems.

You really want to apply a filter to your data that the calibration curve represents, which seems to be your conceptual approach, only frequency domain filtering doesn't involve overlapping and windows, which one does in spectral estimation.

The hard part is to convert your calibration curve into a filter.

• Thanks! I was hoping to speed up processing of long signals by splitting it up into smaller signals... hence my hacky proposal. Can you elaborate on why its hard to convert the calibration curve into a filter? I thought it was as straightforward as multiplying my signal fft magnitudes by relevant constants (interpolated from my calibration data to fit the fft size). I've been doing some quick reading on FIR filters... as I understand.. they are basically just a efficient method of running convolution which is what I understand my approach is. Or perhaps (likely!) I'm missing something? Commented Aug 12, 2018 at 20:54
• Calibration curves usually just give magnitude. Phase is typically not given so one needs to make an informed guess.
– user28715
Commented Aug 12, 2018 at 21:05
• if i take an approach like a filtfilt (matlab), where i apply a second identical filter on the reverse of the timeseries, can i get around filter issues? (and of course adjust my filter magnitude accordingly) Commented Aug 12, 2018 at 21:09
• Could work try it
– user28715
Commented Aug 12, 2018 at 21:17

I agree with @user28715 answer. The best method is to apply a filter to your timeseries to get calibrated timeseries.

# Filter

You did not specify which language you are using, but in Matlab I use the designfilt function. https://www.mathworks.com/help/signal/ref/designfilt.html

d = designfilt('arbmagfir',...);
a = 1;
b = d.Coefficients;


or you could use
b = fircls(N,f,amp,up,lo);

I don't know how to do this in Python, but there may be an equivalent.

# Matlab

## Impulse response

N is the length of the timeseries; M is the length of your impulse response;

M = 200;
p = zeros(M);
p(1) = 1;
h = filter(b,a,p);


But I only showed the above syntax to illustrate the equivalent to the python method below. Really you would just use:

h = filter(d,p);


## Convolution method

u = conv(x, h);
u = u(0:N);


## Inverse Fourier transform method

z = ifft(fft([x zeros(1,M-1)], nFFT) .* fft([h zeros(1,N-1), nFFT));


# Python

## Impulse response

p = np.zeros(200)
p[0] = 1
h = signal.lfilter(b, a, p)


## Convolution method

u = signal.convolve(x, h)
u = u[0:N]


## Inverse Fourier transform method

z = ifft(fft(x, nFFT) * fft(h, nFFT))

• Am I correct in understanding it would be beter to apply the filtfilt (intead of filter) functions to correct for phase offsets (and adjust the filter design accordingly)? What was holding me back from this approach is that I'm trying to do this in R. It's important that I understand the algorithms (hence not specifying a language here) behind the functions so I can write equivalent R code. Do you have insight on how MATLABs designfilt function estimates the poles and zeros? Commented Mar 26, 2020 at 12:26

I am trying to do the same. My idea is to apply a digital filter based on the sensitivity/frequency curve, in order to calibrate my signal. Have you done this successfully?

• (This should be a comment, but I'll respond regardless :p). Yes, but there is no perfect solution. My preferred approach is: 1) I apply a fft to my entire signal 2) Multiply the signal by interpolated calibration values for each frequency, 3) Apply the ifft. You can see my R code for this here. Basically my approach above, but skip the windowing. Seems to work well for me, although I have not properly validated with simulations yet. Commented Mar 18, 2020 at 13:25
• I have not tried @user28715's suggestions of making a proper filter matching my calibration curve yet... as I know of no way to analytically make a appropriate filter for each new set of calibration values. i.e. As far as I'm aware, I'd have to visually drop poles in the z-domain plot until I stumble upon something that closely matches my calibration curve. But this would be more accurate than my approach. Ps.. I'm expecting to look at this again next week... so I'll let u know if I figure it out Commented Mar 18, 2020 at 13:30
• check Hilmars comment on my followup question here. This seems like the most elegant approach to implement user28715's answer (with no dependencies on MATLAB toolbox functions). Commented Mar 27, 2020 at 11:15