In MNE-python, why is the power data scale from time-frequency representation (tfr) different from power spectral density (PSD) ? - matlab

When I managed my EEG data, the results of mne.time_frequency.tfr_morlet (or the other two methods) were an array of power around 1e-7. When being plotted with dB = 'True', a good graph was got only when the scale of color is around -150 to -200. However, when I did the psd analysis, the power is around 0-40. What made the differences? Besides, I also did time-frequency analysis with eeglab on matlab, the color scale of dB is around -40 to 40. I cannot understand the differences. Who can explain it, thanks.
The tfr of MNE-python
The psd of MNE-python
The tfr of eeglab(matlab)

Your question is "why is the PSD different from the time-frequency power?" The PSD does not report based on time.
The time-frequency analysis shows you WHEN different frequencies appear in your data, whereas the PSD gives you the average power of the frequencies within your epoch. At least, from my understanding.
You added 2 images of tfr output and 1 image of psd output--so I assume you are comparing the 2 tfr outputs to the 1 psd output.

Related

Measure spike correlation over time for different neurons

I´m trying to find a global measure of similarity for spikes trains over time. The signals look like in the picture (in this example I have 17 neurons).
Can I use windowed cross correlations? If yes, what should I do with the output matrices? I use MATLAB by the way.
Yes, you can use binned spikes or binned bursts to compute the cross correlations. You can then threshold the output matrix to see what electrodes have the most similarity.
If you have the spikes in text format or have exported your spike train to an HDF5 file from MC_Rack, you can use MEAnalyzer to compute and export all the comparisons: https://github.com/RDastgh1/MEAnalyzer (but please cite it if you use it).

Suggestions for defining limits of frequencies in Matlab Spectrogram function?

I am new to Matlab and signal processing. I am having an issue with defining the frequency range in which the spectrogram is processed. When I am plotting the spectrogram of .wav audio data, the y axis, frequency, spans from zero to around 23 kHz. The useful data I am looking for is in the range of 200-400 Hz. My code snippet is:
[samFa, fs] = audioread('samFa.wav'); %convert audio to numerical data
samFa = samFa(:,1); %take only one channel of numerical output
spectrogram(samFA,2205,1200,12800, fs,'yaxis','MinThreshold',-80);
I don't want to be some noobie that runs into a problem and instantly gives up and posts a duplicate question to stackoverflow, so I have done as much digging as I can, but am at my wit's end.
I scoured the documentation for parameters or ways to have Matlab only analyze a subset or range of the data, but found nothing. Additionally, in all of the examples the frequency range seems to automatically adapt to the data set.
I know it is possible to just calculate the spectrogram for the entire range of frequencies, and then remove all of the unnecessary data through truncating or manually changing the limits in the plot itself, but changing plotting limits does not help with the numerical data.
I went searching through many similar questions, and found an answer all the way from 2012 here: Can I adjust spectogram frequency axes?
where the suggested answer was to import a vector of specific frequencies for the spectrogram to analyze. I tried passing a vector of integer values between 200 and 400, and a few other test ranges, but got the error:
Error using welchparse>welch_options (line 297)
The sampling frequency must be a scalar.
I've tried passing the parameter in at different places in the function, with no avail, and don't see anything regarding this parameter in the documentation, leading me to believe that this functionality was possibly removed sometime between 2012 and now.
When plotting spectrogram without providing signal frequency, Matlab provides a normalized spectrogram, which only provides a much smaller data window, which I can visually assess to cover the data from 0:5kHz (an artifact of overtones in the audio), so I know that matlab is not finding any data above this range to make the frequency range go to 20kHz
I've been trying to learn some signal processing for this project, so I believe the Nyquist frequency should be the maximum frequency that a Fourier transform is able to analyze, to be half the sampling frequency. My recording frequency is sampling at 44,100 Hz, and the spectrogram is ranging to around 22 or 23 kHz, leading me to believe that it's Matlab is noticing my sampling frequency and assuming that it needs to analyze up to such a high range.
For my work I am doing I am needing to produce thousands of spectrograms to then be processed through much further analysis, so it is very time consuming for Matlab to be processing so much unecessary data, and I would expect there to be some functionality in Matlab somehow to get around this.
Sorry for the very long post, but I wanted to fully explain my problem and show that I have done as much work as I could to solve the problem before turning for help. Thank you very much.
Get the axis handle and set the visual range there:
spectrogram(samFA,2205,1200,12800, fs,'yaxis','MinThreshold',-80);
ax=gca;
ylim(ax, [0.2,0.4]); %kHz
And if you want to calculate specific frequencies range to save time you better use goertzel.
f = 200:10:400;
freq_indices = round(f/fs*N) + 1;
dft_data = goertzel(data,freq_indices);

Plotting Acoustic Waveform - Magnitude on a Linear Frequency Scale

I have an acoustic waveform of a Spanish phoneme and I'd like to compute its magnitude spectrum and plot it in dB magnitude on a linear frequency scale. How would I be able to accomplish this in MATLAB?
Thanks
First a quick heads up: At stackoverflow you are expected to show some of your own efforts to solve the problem and then ask for help.
Now to your question:
You can plot the spectrogram using the "spectrogram" Matlab function.
[s,f,t] = spectrogram(x,window,noverlap,f,fs)
Check the details here: https://www.mathworks.com/help/signal/ref/spectrogram.html
For a speech signal you will want to specify the sampling frequency "fs" (you can get that when you read the file using:
[y,Fs] = audioread(filename)
You will probably want to specify the variables "window" and "noverlap" since speech signals can show distinct properties depending on the dimension of the window (fast phenomena will not be visible on big windows ). A typical values are 20ms windows with 10ms overlap (select the best value by considering your sampling frequency and the nearest 2^n value for fast Fourier calculation).
The window size and overlap are also valid when you calculate spectrum. If you apply FFT to the whole waveform then you will get the "average" spectral information for the sentence. To catch specific phenomena you must use windowing techniques and perform a short-term Fourier analysis.
use sptool
Signal Processing toolbox Show its Document

About conversion to dB

So I have been dealing with the hydrophone data and coding in matlab. I have couple of questions as follows -
1. I read all the .wav files in matlab and trying to compute the Power spectral density using pwelch in matlab which im able to do with ease. My question is conversion to dB. The hydrophone output is in Voltage/Micropascal. So in order to obtain the Power spectral density values in dB do I simply do 120 + 10*log10(Power)? This is what i did and the Power in brackets here is the output of using pwelch and the values are like 10 power of -6..
How do I get sound pressure levels(SPL (dB re 1 micropascal) from the power spectral density values in dB?
How do I chose specific frequency band of interest, say I want to look at power spectral density in the frequency 10 to 12kHz then how do i go about?
Many thanks .

Finding Relevant Peaks in Messy FFTs

I have FFT outputs that look like this:
At 523 Hz is the maximum value. However, being a messy FFT, there are lots of little peaks that are right near the large peaks. However, they're irrelevant, whereas the peaks shown aren't. Are the any algorithms I can use to extract the maxima of this FFT that matter; I.E., aren't just random peaks cropping up near "real" peaks? Perhaps there is some sort of filter I can apply to this FFT output?
EDIT: The context of this is that I am trying to take one-hit sound samples (like someone pressing a key on a piano) and extract the loudest partials. In the image below, the peaks above 2000 Hz are important, because they are discrete partials of the given sound (which happens to be a sort of bell). However, the peaks that are scattered about right near 523 seem to be just artifacts, and I want to ignore them.
If the peak is broad, it could indicate that the peak frequency is modulated (AM, FM or both), or is actually a composite of several spectral peaks, themselves each potentially modulated.
For instance, a piano note may be the result of the hammer hitting up to 3 strings that are all tuned just a tiny fraction differently, and they all can modulate as they exchange energy between strings though the piano frame. Guitar strings can change frequency as the pluck shape distortion smooths out and decays. Bells change shape after they are hit, which can modulate their spectrum. Etc.
If the sound itself is "messy" then you need a good definition of what you mean by the "real" peak, before applying any sort of smoothing or side-band rejection filter. e.g. All that "messiness" may be part of what makes a bell sound like a real bell instead of an electronic sinewave generator.
Try convolving your FFT (treating it as a signal) with a rectangular pulse( pulse = ones(1:20)/20; ). This might get rid of some of them. Your maxima will be shifted by 10 frequency bins to teh right, to take that into account. You would basically be integrating your signal. Similar techniques are used in Pan-Tompkins algorithm for heart beat identification.
I worked on a similar problem once, and choosed to use savitsky-golay filters for smoothing the spectrum data. I could get some significant peaks, and it didn't messed too much with the overall spectrum.
But I Had a problem with what hotpaw2 is alerting you, I have lost important characteristics along with the lost of "messiness", so I truly recommend you hear him. But, if you think you won't have a problem with that, I think savitsky-golay can help.
There are non-FFT methods for creating a frequency domain representation of time domain data which are better for noisy data sets, like Max-ent recontruction.
For noisy time-series data, a max-ent reconstruction will be capable of distinguising true peaks from noise very effectively (without adding any artifacts or other modifications to suppress noise).
Max ent works by "guessing" an FFT for a time domain specturm, and then doing an IFT, and comparing the results with the "actual" time-series data, iteratively. The final output of maxent is a frequency domain spectrum (like the one you show above).
There are implementations in java i believe for 1-d spectra, but I have never used one.