I am doing analysis on acoustic data to estimate speed of sound propagation in a flowing fluid through a pipe. The slopes of the bright straight lines in the frequency-wavenumber spectrum of the acoustic data are equivalent to speed of sound in a flowing fluid in the flow direction and the opposite direction, respectively. I am trying to implement a technique to estimate the slope of the x-shape in the frequency-wavenumber spectrum shown in the figure below so that I can estimate the SoS. The technique that I am using is to loop over the rows (frequency bins) of the plotted data. Then, slope for each point is estimated (=f-coordinate/k-coordinate) for each cell in the rows. Then, the pixel intensity is averaged for cells that have the same slope over the entire data. Finally, intensity is plotted versus slope (which is equivalent to speed of sound in my analysis). The slope /SoS at the peaks correspond to the slopes of the straight lines in the frequency-wavenumber spectrum. The approach works well but still introduces some error as shown in the sub-figure. Is there anyway to improve the accuracy of this technique? Is there any other techniques that can be used for the same purpose? Is there any pre- or post-processing steps that can improve the peak resolution without shifting peak’s location?
1 Answer
You could consider using filtfilt
(available in MATLAB, Octave and Python scipy.signal) which is a zero-phase (non-causal) post-processing filter which will smooth the result without shifting the peak. For example you could do a moving average over 10 samples twice (filtfilt filters the signal in the forward and reverse direction resulting in zero phase) by doing the following in Python:
my_result = scipy.signal.filtfilt(np.ones(10),10, my_waveform)
Another option is to curve fit versus a Lorentzian resonance which I suspect would represent the resonance reasonably well. This would be more complicated than the first suggestion but provide even higher accuracy. This could be done in Python (or other similar tools) with scipy.optimize.curvefit.
-
$\begingroup$ Thanks for your help. I tried to use the suggested zero-phase filtering technique and it provides really good results. But this may raise another question about whether if there is a proper way to decide the optimum size of the smoothing window. Samll window size doesn't provide proper smoothing, while large window size may result in losing some details of the raw data. $\endgroup$– user67390Commented Aug 19 at 19:38
-
$\begingroup$ Yes that requires a lot more information about the statistics of the noise and signal specifically. Those details would go way beyond what I could provide here but you can do a simple trial and error optimization. Glad it helped! $\endgroup$ Commented Aug 20 at 0:09