Closed LobsterMan123 closed 2 years ago
I just checked the "Freq_theta_Num_29_FrequencyValues.txt" file and I can see that the point at index 1 is ,in fact, the peak. Just a quick note, in MATLAB indexing starts from 1, in Java/Python it starts from 0.
0|6343.6353132
1|15120.646817172741
2|2314.137785381897
3|207.12337507802246
Quite clearly, index 1 is the peak in the neighbourhood. I am not sure what the issue is here. Could you please clarify?
Yes, my reason for asking the question is because if you look closely at the graph/plot, the very first data point (6343.6353132) - which is not a peak - does not intersect on the built-in plot grid line at '0' but instead appears to be at '1.' This would make the second data point (15120.646817172741) - which is the actual peak - thus located above '2' not '1.' The plot image is remarkably high-res and zooming into the region clearly shows that the very first data point (6343.6353132) is not positioned at '0.' This is why I was confused, as I was consulting the plot initially. If this is just a quirk of the plotting utility, that is fine, I'll just plot the data with Excel or something, but I wanted to make sure I wasn't interpreting things incorrectly. Thanks.
LM
Can you please add the whole code (including the plotting code) here?
Certainly. Below is the code for obtaining the DFT and how I saved the results to a file:
_Fourier ft = new FastFourier(XArray); ft.transform(); boolean onlyPositive = true; double[] xOut = ft.getMagnitude(onlyPositive); // Print frequency spectrum - only positive values try { PrintWriter writer = new PrintWriter(cwd + File.separator + "AngleNum" + counter + "_FrequencyValues.txt", "UTF-8"); for (int b = 0; b < xOut.length; b++) { writer.println(b + "|" + xOut[b]); } // END 'for' writer.close(); } // END 'try' catch (FileNotFoundException ex) { System.out.println("Unable to open the file"); } // END 'catch' catch (IOException ex) { System.out.println("Cannot read the file"); } // END 'catch'
Below is the code for detecting peaks and storing them in a file:
FindPeak dftFp = new FindPeak(xOut);
Peak middleMan = dftFp.detectPeaks();
int[] peaks = middleMan.getPeaks();
//System.out.println(peaks.length + "\n");
System.out.println("Residue: " + counter);
try {
PrintWriter writer3 = new PrintWriter(cwd + File.separator + "Angle_Num_" + counter + "AllTransformPeaks.txt", "UTF-8");
for (i = 0; i < peaks.length; i++) {
writer3.println(peaks[i]);
}
writer3.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open the file");
} // END 'catch'
catch (IOException ex) {
System.out.println("Cannot read the file");
} // END 'catch'
Now here is the code to plot the frequencies:
width = 600; // original value was 600
height = 500; // original value was 500
title = "AngleNum " + counter + " Angle Transform";
x_axis = "Frequency";
y_axis = "Angle Magnitude";
Plotting xFrequencies = new Plotting(width, height, title, x_axis, y_axis);
xFrequencies.initialisePlot();
xFrequencies.addSignal("AngleNum " + counter + " Angle1", xOut, false);
xFrequencies.saveAsPNG("AngleNum_" + counter + "_AngleFrequencies.png");
I am iterating this code over many input files to be plotted and that is where the "counter" variable is from.
So, this happens because by default, the X axis starts counting from 1 when we plot it. JDSP uses xchart
as a dependency for plotting and by default, xchart
starts counting points from 1. That's the reason, your plot starts from 1 instead of 0.
To resolve this, all you need to do is:
double[ ] bOut = UtilMethods.arange(0, xOut.length, 1.0);
xFrequencies.addSignal("AngleNum " + counter + " Angle1", bOut, xOut, false);
Ok, thanks for explaining this. So as it turns out, for my data, my frequency interval was 1.875 MHz. Does this then mean that the data file I initially provided:
0|6343.6353132 1|15120.646817172741 2|2314.137785381897 3|207.12337507802246
should instead look like this?
0|6343.6353132 (1.875 1)|15120.646817172741 (1.875 2)|2314.137785381897 (1.875 * 3)|207.12337507802246
In other words, is the very first frequency data point output by JDSP's FFT always correspond to a frequency of '0?' Since the peak detection feature says the very first peak is at position '1' (from my initial data file) it sounds to me that the very first frequency data point provided by the FFT algorithm will indeed always correspond to a frequency of '0,' but I just want to verify with you that this assumption is correct. Thanks again.
LM
Other than the sampling frequency, DFT bins are also dependent on the signal length, so it might not be the case.
I would recommend using the getFFTFreq()
function introduced in v2.0.0 to get the corresponding frequency bins.
Ok, thanks, I'll check it out then.
LM
I went ahead and implemented the getFFTFreq as follows:
_Fourier ft = new FastFourier(XArray);
ft.transform();
boolean onlyPositive = true;
double[] xOut = ft.getMagnitude(onlyPositive);
double[] freqBins = ft.getFFTFreq(1, onlyPositive);
try {
PrintWriter writer2 = new PrintWriter(cwd + File.separator + "RealFreqBins.txt", "UTF-8");
for (int w = 0; w < freqBins.length; w++) {
writer2.println(freqBins[w]);
} // END 'for'
writer2.close();
} // END 'try
This yielded the 'freqBins' array, and therefore my output file, as having a total of 32769 bins/x-axis items.
The first 4 reported frequency bins are: 0.0, 1.52587890625E-5, 3.0517578125E-5, 4.57763671875E-5 and the very last reported frequency bin is 0.5.
My question is what are the units that JDSP is working with when I give it a '1' for my sampling frequency? Therefore, what are the units of the frequency bins that the getFFTFreq() is giving me as output that I listed above (i.e. 0.0, 1.52587890625E-5, 3.0517578125E-5, 4.57763671875E-5)? I provided a '1' to the 'getFFTFreq()' method for the sampling frequency because the sampling frequency for data collection that I used was collecting my time domain data every 1 nanosecond. Thanks.
LM
When nothing is provided as the sampling frequency, the sampling frequency is set to 1 which represents the normalised frequency scale. To know more about normalised frequency, please use this link.
Ok. So all I want is for the output results of the code I used above:
double[] xOut = ft.getMagnitude(onlyPositive);
double[] freqBins = ft.getFFTFreq(1000000000, onlyPositive); //I collected data every 1 billionth of a second
to give me output data, that if I were to plot it directly, would show me what frequencies in Hz are present in my raw data (since my supplied "Fs" value to JDSP was in Hz - it is indeed 1 billion Hz) - I assume any peaks in such a plot of "xOut" vs. "freqBins" indicate the frequencies present in the raw/collected data. Is the above code snippet sufficient to give me this if I were to plot its output ("xOut" vs. "freqBins") without additional manipulation?
LM
Yes
Hello,
I plotted the data in the file named "Freq_ANGLE_PER_NUM_29_theta.txt" (shown below)
and then I obtained the DFT for that same data and plotted it (shown below)
I also stored this DFT output data in the file named "Freq_theta_Num_29_FrequencyValues.txt" (I included index/predictibly increasing numbers as part of this data, but they are not provided from the JDSP code).
I then wanted to find out where the peaks were and so I used the following code on the DFT version of my data: FindPeak dftFp = new FindPeak(xOut); Peak middleMan = dftFp.detectPeaks(); int[] peaks = middleMan.getPeaks(); //System.out.println(peaks.length + "\n"); System.out.println("Residue: " + counter);
The results from this peak-determining code indicated that the very first peak/maximum was located at the x-axis value of '1' when the plot by contrast seems to show that the very first peak is instead located the x-axis value of '2.'
I stored the location results of all peaks in the file named "Freq_theta_Num_29AllTransformPeaks.txt"
Am I reading/interpreting the output data incorrectly (all data files referenced to in this message are attached Freq_ANGLE_PER_NUM_29_theta.txt
Freq_theta_Num_29_FrequencyValues.txt
Freq_theta_Num_29AllTransformPeaks.txt )? Why does the plot seem to indicate the peak is at one position, but the peak-detecting analysis with the library declares the peak is at another?
Thanks.
LM