Project B: A Program to Demonstrate the Fourier Transform Technique in NMR Spectroscopy.
- You have to write a computer program
that creates a set of superimposed cosine waves of different frequencies,
multiplies them by a decaying exponential function, Fourier transforms the data
and displays the result on a terminal.
- You have to transfer the
data to a Macintosh computer and plot it using the Cricket Graph program.
Many types of physical measurement in chemistry
involve obtaining data as a function of time ('time domain' data). In NMR
spectroscopy for example the spectrometer actually measures a set of frequencies
as a function of time by monitoring the 'Free Induction Decay'. This signal
actually looks like a decaying cosine wave, but when many such waves are
superimposed, the resultant signal is almost impossible to interpret visually.
The technique of Fast Fourier Transform (FFT) transforms the 'time domain'
signal into a 'frequency domain' signal, where each characteristic frequency is
displayed as a single line rather than as a cosine wave. This project involves
writing a program to generate a defined number of cosine curves (ca 1-5),
to add them together, to weight them by multiplying by an exponential function
and then to Fourier transform the result. Such a program can be used to
illustrate many of the fundamental properties of the FFT technique as applied in
chemical instrumentation. The actual Fast Fourier Transform routine (FASTF) is
provided for you automatically when you link the program. You just write the
Procedure to calculate a Fourier Transform
Use the command ugfor to enter the Fortran
environment on the Indigo workstations. In the instructions below,
you do not need to derive any equations, which are shown in bold type,
along with any variables that you need to define.
- Write code to
dimension (maximum 1024) the following one-dimensional arrays;
XREAL, XIMAG. The array BROAD will contain the decaying exponential
function, FID the superimposed cosine waves before weighting with BROAD, and
XREAL and XIMAG are the so called 'real' and 'imaginary' parts of the of Fourier
- Write code to define a character array TITLE to
contain column headings and open a new file 'cricket.dat' which will contain
data to be used by the Macintosh program Cricket Graph.
- Define a
character variable TAB*1, and set it equal to;
TAB = CHAR(9). Here, 9
represents the 'ascii' code for the TAB character, which will be needed later
for writing out the data file 'cricket.dat'
- Write code to input the
total number of spectral points N (Maximum 1024), to check that this
number is exactly a power of 2 (ie 2**n) and to zero all the above arrays prior
to calculation. Read in also T1, the initial time delay before
measurement of the signal commences. The default value of T1 should be 0.
- Write code to input a frequency K and its intensity AI of a
cosine curve. K is simply how many 2 ¼ cycles will occur within the space of
the total data points N. Note that you need at least two data
points to define a cycle of the cosine, and hence K < N/2 (the Nyquist
Theorem). The fraction of a cosine wave between any two adjacent data points (in
radians) is defined by;
STEP = ¼ * K / (N/2) = ¼ * K * 2 / N
Make sure that STEP is a floating point number by correctly
converting any integers (ie N or K) using the intrinsic function FLOAT.
- Write code to evaluate the value of the cosine curve at each of the total number
of points N using the equation for the nth point (1 <= n <=
FID(n) = FID(n) + AI* COS (
Here n (for NMR data at least) has the
units of time, and the n-1 arises because you are assumed to measure the
value of the FID at time = 0 (ie 1-1) rather than at time=1. T1 corresponds to
any time delay before acquisition of the signal. This delay has important
consequences regarding the phase of the signal (see below).
- Read in the
frequency K and the intensity AI of the next cosine curve (if any) and repeat
the above steps up to a maximum of five. After the last desired frequency, you
should have an array FID cotaining N points each value of which corresponds to
the sum of a number of superimposed cosine waves.
- You will now need to
evaluate BROAD(n) for each of the N points. BROAD is defined
BROAD(n) = EXP (-BR * ((n-1)/N) )
BR is a broadening factor. Note that in the above expression, real and integer
numbers are (incorrectly) mixed and your own code should correct this using the
FLOAT function. If BR = 0, BROAD(n) = 1; if BR > 0, BROAD contains a
decaying exponential function. It turns out the the value of BR controls the
WIDTH of the lines contained in XREAL after Fourier transformation. If BR = 0,
the lines are infinitely narrow. This might cause arithmetic problems, and you
should ensure in your code that BR > 0 under all conditions.
code to multiply arrays BROAD and FID together and put the product in array
- Call the subroutine FASTF(XREAL,XIMAG,N). This subroutine is
'linked' in using ugfor. Click here to see the source code.
* After calling the subroutine, XREAL and XIMAG contain the
real and imaginary parts of the spectrum. Actually, only the first N/2 data
locations of each array contain the spectrum (see the Nyquist Theorem above).
Write code to normalise each array such that the maximum value of any element in
each array is 1 (ie the absolute intensity of the cosine waves is arbitrary).
- Write out to the terminal screen the following five variables per line for
n=1 to N;
n-1, BROAD(n), FID(n),
n-1 corresponds to the
frequency of the cosine curves present in the FID, and has the value n-1
because the contents of XREAL(1) actually correspond to a zero cosine
- What should have happened by now is the following. If you
defined N=128 data points, and requested cosine frequencies of say
K=4, 17, 24 and 52 with intensities of say AI=1.0, 2.0, 2.0 and 1.0,
the values of the variables XREAL(5), XREAL(18), XREAL(25) and XREAL(53) should be
1.0, 2.0, 2.0 and 1.0. The other locations should contain smaller number, but
will not be zero if you used BR != 0, ie the lines are not infinitely narrow.
This means the 'spectrum' contains lines at frequencies of 4, 17, 24 and 52 with
intensities in the ratio 1,2,2,1.
- Check you program is working by
trying some of the following;
- Alter the intensity of each cosine curve
and verify the absolute value of XREAL(n) changes accordingly.
around with the broadening factor and verify that larger values of BR lead to
- Try entering a value of the cosine frequency that is larger
than N/2 and see what happens. The phenomenon is known as 'folding' and is a
cause of many 'operator' errors during 'real' FT NMR spectroscopy.
entering non-zero values of T1. This quantity is called the 'first order phase
correction'. What effect does T1 have on the contents of XREAL and XIMAG?
Actually, on a real spectrometer, 0<T1<1, and corresponds to the finite
time taken for the electronics to respond before acquisition of the signal can
- For the more adventurous, try changing the algorithmic form of
BROAD. Many different weighting functions are used in NMR spectroscopy, and each
is used to 'massage' the data in different ways. You could try two successive
functions, ie an exponential function followed by a Gaussian function centred in
the middle of the Free induction decay.
Procedure to Display a Fourier Transform
The final stage is to display this data and to
obtain 'hardcopy'. Write out in your program the N values of the integer
n-1 and the arrays BROAD(n), FID(n), XREAL(n) and
XIMAG(n) in the following format to the file cricket.dat;
Time/Freq TAB BROAD TAB FID TAB XREAL TAB
0 TAB 1.0000 TAB 1.0000 TAB 0.0228 TAB 0.0000
TAB 0.9922 TAB 0.1111 TAB 0.0241 TAB 0.0726
N N N/2 N/2
The first row
after the * contains the five titles of each column (the above are only
suggestions, you can try your own). These will appear eventually to identify the
data in the plotting program. TAB means write out character variable TAB =
CHAR(9) between each column of data. Using this method, you can write out the
full N points of the Time/Freq, BROAD and FID arrays, and only N/2 points of the
XREAL and XIMAG arrays. Remember however, that only the first N/2 values of
XREAL(n) and XIMAG(n) represent the actual spectrum. Can you interpret what the
values of XREAL(1 + N/2) through to XREAL(N) correspond to by inspection of the
Transfer the file cricket.dat to a Macintosh
Computer located in room 170 and plot the contents using the program Cricket
Graph. See here on how to mount an Indigo file on a Macintosh
If you want to see how the output
of the program should look, you can try running the "executable" only version of
the program by typing
from the console window. The
project handed in should of course correspond to your own listing of this
Copyright (c) B. P. Levitt, H. S. Rzepa and ICSTM Chemistry Department, 1994.
Return to Index page