Usama
Usama

Reputation: 31

fft of a biosignal of unknown frequencyin python

I am trying to make a software so that I could use to analyse the data that I have on a file. I don't have information on the sampling rate at which the data was captured. Is there a way to find the frequency of my signal given that I can play around with the sampling rate of my signal? I tried writing a code to find the FFT of a sine wave that has a frequency of 100 Hz but when I plot fft of my signal, the frequency of the signal does not match the frequency on the fft axis. Here is the complete code for your reference.

from scipy import *
import numpy as np
import matplotlib.pyplot as plt
from Tkinter import *
import tkFileDialog

class FFTGUI(object):
    def __init__(self, master):
        self.master = master
        self.layout_init(self.master)

    def layout_init(self, master):
        self.master = master
        self.title_label = Label(self.master, text="SIGNAL ANALYSER", font="-weight bold")
        self.title_label.grid(row=0, column=0, columnspan=2)

        self.load_data_file_label = Label(self.master, text="LOAD DATA: ")
        self.load_data_file_label.grid(row=1, column=0)

        self.load_data_file_button = Button(self.master, text="LOAD",command = self.askopenfilename)
        self.load_data_file_button.grid(row=1, column=1)

        self.no_sample_label = Label(self.master, text="ENTER THE NUMBER OF SAMPLE POINTS: ")
        self.no_sample_label.grid(row=2, column=0)

        self.no_sample_entry = Entry(self.master, text="Enter Sample")
        self.no_sample_entry.grid(row=2, column=1)

        self.sample_spacing_label = Label(self.master, text="ENTER THE SAMPLING SPACE (s):")
        self.sample_spacing_label.grid(row=3, column=0)

        self.sample_spacing_entry = Entry(self.master, text="ENTER SPACE")
        self.sample_spacing_entry.grid(row=3, column=1)

        self.plot_graph_button = Button(self.master, text="PLOT", command = self.fft_data_plot)
        self.plot_graph_button.grid(row=4, columnspan =2)

    def askopenfilename(self):
        # get filename
        self.filename = tkFileDialog.askopenfilename()
        # open file on your own
        #~ print self.filename
        if self.filename:
            return open(self.filename, 'r')

    def selectfile(self):
        self.file = tkFileDialog.askopenfilename(parent=root,mode='rb',title='Choose a file')
        if self.file != None:
            self.f= np.loadtxt(file, delimiter='\t', skiprows=0, unpack=True)
            #~ print type(f)
            return f

    def fft_data_plot(self):
        N = int(self.no_sample_entry.get())
        SAMPLE_SPACE_T = int(self.sample_spacing_entry.get())
        T = 1.0/SAMPLE_SPACE_T
        lines = [line.rstrip('\n') for line in open(self.filename)]
        lines = [float(i) for i in lines]

        #~ print lines
        yf = fft(lines)
        yf_power = np.abs(yf)**2
        energy_yf = 0

        for i in range(N/2):
            energy_yf += yf_power[i]
        #~ print energy_yf

        energy_nor_yf = []
        for i in range(N/2):
            temp_energy_nor_yf = (yf_power[i]/energy_yf)*100
            energy_nor_yf.append(temp_energy_nor_yf)
        #~ print energy_nor_yf


        plt.subplot(3,1,1)
        plt.plot(lines)

        plt.subplot(3,1,2)
        plt.plot(np.abs(yf))
        plt.ylim([0,100])
        plt.xlim([0,N/2])
        plt.subplot(3,1,3)
        plt.plot(energy_nor_yf)
        plt.ylim([0, max(energy_nor_yf)])
        plt.show()



root = Tk()
FFTGUI(root)
root.mainloop()

The file I am trying to load and analyse can be found here: http://www.filedropper.com/cosine100hz This file is a simple cosine wave that I generated on excel and resulting data of the cosine wave was added in a text file so that it could be plotted and analysed. Unfortunately, I dont seem to know what the issue is and why I am not getting the desired frequency. I would appreciate your help. Thanks

Upvotes: 0

Views: 371

Answers (1)

abukaj
abukaj

Reputation: 2712

The only way I know to obtain frequency from pure samples is to know some frequency present in your signal (e.g. power grid frequency artefact in EEG data).

[EDIT]

Since there is a known frequency in your signal, you may find the sampling ratio (or rather sampling interval). If you use numpy.fft.fft() (I guess scipy.fft() method is an alias for it), you can obtain frequencies of respective components with numpy.fft.fftfreq().

The first argument of numpy.fft.fftfreq(n, d=1.) is the number of samples, while the second (d) is the sampling interval (1/f). You need to find an appropriate d.

Upvotes: 1

Related Questions