5.12 Signal Processing with LabTalk


Summary

Origin provides a collection of X-functions for signal processing, ranging from smoothing noisy data to Fourier Transform (FFT), Short-time FFT, Convolution and Correlation, FFT Filtering, and Wavelet analysis. In this tutorial, using an example shows how to perform 1D FFT on the data.

What You Will Learn

This tutorial will show you how to use Labtalk script to:

  • Import the specified files with a pre-defined filter
  • Perform FFT (Fast Fourier Transform) on multiple files
  • Loop all the files
  • Save location of FFT peak to a summary sheet, and plot the peak locations as a function of variable from file name
  • Performs a linear fit, and then return the value of slope and intercept


Steps

Create a result sheet

Run the script below to change the Project Explorer directory and open a new workbook using the pe_cd and newbook x-functions. Then define ranges for columns and assign long names and units.

// Set Project Explorer folder to root
pe_cd /;
// Create a new book to hold result from FFT analysis,
// and the short name of the new book will be stored to the string '''ResultBook'''
newbook result:=ResultBook$;

// Define ranges for columns 1 and 2 to save results later. 
// (Multiple range variables can be declared on the same line, separated by comma.)
range rx = 1, rp = 2;
// Set long name and units for the columns 1 and 2
rx[L]$ = "X";
rx[U]$ = "mm";
rp[L]$ = "Peak Frequency";
rp[U]$ = "kHz";

Searches the files with the string

Using a wildcard, searches for files in the path <Origin EXE Folder>\Samples\Signal Processing\ using the findfiles x-function. Count the files.

// Point to where the data files are
string path$ = system.path.program$ + "Samples\Signal Processing\";
// Find all files ''TR*.dat''
findfiles ext:="TR*.dat";
// Get the number of files. LF means Line feed.
int numFiles = fname.GetNumTokens(LF);

Perform FFT on files by loop script

Perform FFT on one file
After finding the TR*.dat files, you import them, perform FFT and save the location of FFT peak to a summary sheet. This example details steps for executing these actions on one data file.

  1. Get the file name and import data file using an import filter TR Data Files.oif that exists in data folder. The filter does some post processing of the data by creating frequency column and setting values etc.
    The x-function pe_mkdir and impFile are used in this case.
    // Declare ''ifile'' integer variable as the files index. 
    // For the first file, here set this variable to 1
    int ifile = 1;
    
    // Create two string variables 
    string filepath$, file$;	
    // Get file name 
    filepath$=fname.gettoken(ifile,LF)$;
    // Parse out just file name without path and without extension
    file$ = filepath.gettoken(filepath.getnumtokens(\),\)$;
    file$ = file.gettoken(1,.)$;
    	
    // Make a new Project Explorer subfolder and set it active
    pe_mkdir file$ cd:=1;
    	
    // Add a new book for importing data file
    newbook;
    // Import file with pre-defined filter that exists in data folder.
    impfile fname:=filepath$ filtername:="TR Data Files.oif" location:=0;
  2. Perform FFT
    // Perform FFT on the columns 2 and 3 of imported data by default in the dialog
    fft1 (2,3);
  3. Find the max peak location, then output the associated frequency value and parse the file name to the ResultBook.
    Use wks.ncols to get the number of columns in the worksheet, and use the limit command to find limiting values for the dataset.
    // Set FFT result sheet active - this should be sheet2 
    page.active = 2;
    // Add a new column in the activate worksheet
    wks.addcol();
    // The new column is the last column in this sheet, 
    // so the column index equals the number of columns in the worksheet
    // Declare a new integer variable ''nmag'' with the number of columns in the worksheet.
    int nmag = wks.ncols;
    // Column 2 should contain complex data, so use that to compute magnitude and find peak location
    // Put the absolute value of the column 2 to the last column
    wcol(nmag) = abs(col(2));
    
    // Find max peak location in last column using limit command
    limit wcol(nmag);
    // Save associated frequency value from column 1 to ResultBook sheet1 column 2 in the PE folder
    // limit.imax means corresponding index for maximum Y value. 
    rp[ifile] = col(1)[$(limit.imax)];
    // Delete the last column
    delete wcol(nmag);
    	
    // Parse filename and get a string value ''aa''
    string aa$ = file.gettoken(2,'R')$;
    aa$=aa.gettoken(1,'M')$;
    // Save ''aa'' value to ResultBook sheet1 column 1
    rx[ifile] = %(aa$);
    
    // Set PE folder to previous level
    pe_cd ..;


Perform FFT on the multiple files
To repeat actions on multiple files, you can use the for loop command. This section shows the complete loop script for importing files, performing FFT and saving the location of FFT peak to a summary sheet.
Note: When you run the loop script in the Script Window, please highlight the entire script, then press the Enter key.

for(int ifile = 1; ifile <= numFiles; ifile++)
{
	string filepath$, file$;
	filepath$=fname.gettoken(ifile,LF)$;
	file$ = filepath.gettoken(filepath.getnumtokens(\),\)$;
	file$ = file.gettoken(1,.)$;
	pe_mkdir file$ cd:=1;
	newbook;
	impfile fname:=filepath$ filtername:="TR Data Files.oif" location:=0;
	
	fft1 (2,3);
	
	page.active = 2;
	wks.addcol();
	int nmag = wks.ncols;
	wcol(nmag) = abs(col(2));
	limit wcol(nmag);
	rp[ifile] = col(1)[$(limit.imax)];
	delete wcol(nmag);
	string aa$ = file.gettoken(2,'R')$;
	aa$=aa.gettoken(1,'M')$;
	rx[ifile] = %(aa$);
	
	pe_cd ..; 
}

Create a new graph by result sheet

After performing FFT on all files, create a scatter plot with X values extracted from the file name and the Peak Frequency value, using the plotxy x-function

// Make ResultBook active
win -a %(ResultBook$);
// Plot XY data with column 1 and 2. 
plotxy (1,2);

Linear Fit

Do a linear regression on the result data and report the slope and intercept. The LR command is used in this case.

//Performs a linear fit on ResultBook sheet1 column2
range bb = [ResultBook$]1!2;
Lr bb;
//''lr.b'' is returned the value of slope
type "Slope is $(lr.b)"; 
//''lr.a'' is returned the value of intercept 
type "Intercept is $(lr.a)";