9.4 Hahn-echo detected EPR script
The following script is for an EPR experiment, measuring the area of a simple (2-pulse) Hahn-echo as a function of the field. Thus it is somewhat similar to the very first script of this chapter, but with the additional complication of adding the creation of pulses and using a digitizer instead of a lock-in amplifier to do the detection:
1 DEVICES: 2 3 dg2020_b; // pulser 4 tds754a; // digitizer 5 er032m; // field controller 6 7 8 VARIABLES: 9 10 start_field = 3400 G; 11 end_field = 3480 G; 12 field_step = 0.5 G; 13 14 pi_half = 40 ns; 15 tau = 200 ns; 16 17 field = start_field; 18 area[ 2 ]; 19 W[ 2 ]; 20 I = 1; 31 32 33 ASSIGNMENTS: 34 35 TIMEBASE: 5 ns; 36 TRIGGER_MODE: INTERNAL, REPEAT_FREQUENCY = 100 Hz; 37 38 MICROWAVE: POD = 1, V_HIGH = 5 V, V_LOW = 0 V; 39 DETECTION: POD = 3; 40 41 42 PREPARATIONS: 43 44 PULSE_1: FUNCTION = MICROWAVE, 45 START = 0 ns, 46 LENGTH = pi_half; 47 48 PULSE_2: FUNCTION = MICROWAVE, 49 START = PULSE_1.START + PULSE_1.LENGTH + tau, 50 LENGTH = 2 * pi_half; 51 52 PULSE_3: FUNCTION = DETECTION, 53 START = PULSE_2.START + PULSE_2.LENGTH / 2 + tau, 54 LENGTH = 10 ns; 55 56 magnet_setup( start_field, end_field ); 57 init_1d( 1, 0, start_field, field_step, 58 "Field [G]", "Echo area [mV * ns]" ); 59 60 digitizer_num_averages( 100 ); 61 digitizer_trigger_channel( AUX ); 62 digitizer_trigger_position( 0.2 ); 63 64 W[ 1 ] = digitizer_define_window( -5 ns, 10 ns ); 65 W[ 2 ] = digitizer_define_window( 200 ns, 10 ns ); 66 67 68 EXPERIMENT: 69 70 WHILE field <= end_field { 71 digitizer_start_acquisition( ); 72 area[ 1 ] = digitizer_get_area( CH1, W[ 1 ] ); 73 area[ 2 ] = digitizer_get_area( CH1, W[ 2 ] ); 74 display_1d( I, ( area[ 1 ] - area[ 2 ] ) * 1.0e12 ); 75 I += 1; 76 fsave( "# # # #\n", field, area[ 1 ], area[ 2 ], 77 area[ 1 ] - area[ 2 ] ); 78 field = magnet_sweep_up( ) 79 } |
As usual, the script starts with the DEVICES
section, telling
fsc2
that the Berlin version of the driver for the
Sny/Tektronix DG2020
pulser, the Tektronix TDS754A
digitizer and the Bruker ER032M
field controller are going to be
used in the experiment.
In the VARIABLES
section we need variables for the field sweep,
i.e. the start and end field and the field sweep with. Then we declare
a variable with the length of a pi-half pulse and the edge-to-edge
distance of the two pulses we're going to use.
Finally, we have a variable for storing the current field, an array with two elements for the echo area and an area off-signal, another array for digitizer window descriptors (to be explained later) and a counter variable.
Then follows a section which we haven't had to deal with until now, the
ASSIGNMENTS
section. It is for the basic set up of the pulser.
As the very first thing (line 35) we need to set the timebase the pulser is going to be used with. It always has to be the first instruction because all timings in later statements concerning the pulser must be integer multiples of this timebase and the program can only check this when it already knows about the timebase.
The next statment sets the trigger mode for the pulser. Here we tell
fsc2
to use the internal trigger of the pulser and to take care
that the repetition frequency is 200 Hz. If we wouldn't set a
repetition frequency (or time), the pulser would repeat the pulse
sequence with the highest possible rate. This wouldn't make to much
sense, not only because didgitizers usually can't sample data that fast,
but also because we need some time for the spin system to relax back to
Boltzmann distribution before applying the pulse sequence again.
The following lines are for setting up pulser functions. Each pulse is
supposed to have a function. Typical functions are MICROWAVE
,
TWT
, RADIO_FREQUENCY
, DETECTION
and many more.
For this simple experiment we only need two functions, we need microwave
pulses and another pulse to trigger the digitizer at the right moment,
i.e. a detection pulse. For each of the used functions the output
channel(s) of the pulser must be defined, i.e. on which of its
connectors the pulse will appear. Here we tell fsc2
to route
microwave pulses to the output pod 1
and the detection pulse to
pod 3
. Additionally, we also set the high voltage for the
microwave pulses to +5 V and the low voltage to 0 V.
The declaration of the pulses happens in the PREPARATIONS
section, starting at line 44. Pulses always start with the word
PULSE
(but which can be abbreviated to a simple P
),
followed by an optional underscore and end in a unique number which must
be non-negative. PULSE_7
, PULSE7
, P_7
and P7
are all legal names of the same pulse. For each pulse at least its
function and start position must be set. As long as its length isn't
set the pulse cannot be used (there is an exception for pulsers that can
generate trigger pulses of only a fixed length).
In line 44 the definition of pulse PULSE_1
(which also could be
called P1
) starts: its function is set to MICROWAVE
,
i.e. it will be output on the pulsers pod designated for microwave
pulses in the ASSIGNMENTS
section, its starting position is
0 ns after the trigger and its length is set to the value stored
in the variable pi_half
.
PULSE_2
is also a microwave pulse, but is starts displaced by a
time tau
after the falling edge of the first pulse,
PULSE_1
. As you can see from the code you can use the properties
of already pulses by a combination of the pulse name, a dot, and the
name of the property.
Finally, PULSE_3
is the trigger pulse for the digitizer. It is
supposed to appear exactly on top of the echo, i.e. after twice the
time between the middle of the first and the second pulse. Its length
isn't really that important, a rather short pulse should do fine.
The next lines starting at line 56 should already be well known from the first script for a normal cw-experiment: the magnet and the graphics get initialized.
Because we use here a digitizer to measure the echo area we also
should set up the digitizer. Calling the function
digitizer_num_averages()
we set the digitizer to always
accumulate the results of 100 repetitions of the pulse sequence.
digitizer_trigger_channel()
tells the digitizer to expect
the trigger signal on its AUX
channel. The next call of
digitizer_trigger_position()
sets the position within the
trace it records. By setting it to 0.2 the digitzer will use a
pretrigger a fifth (of 20%) of the measured trace.
Finally, we must define ranges for measuring the area, otherwise the
digitizer would return the area of the full trace. This is done by
calling the digitizer_define_window()
function, which
expects up to two arguments, the start position of the range (relative
to the trigger position and its length. It returns an integer number
which in the following is used in further function calls for the
digitizer. Here we define two windows, with the first on top of the
echo and another one far of the echo to allow background subtraction.
The window handles returned by the function calls are stored in the
array W
.
Now we are done with all preparations and can start with the
EXPERIMENT
section. The whole experiment is done within a
WHILE
loop, which is repeated until the field has reached the end
field.
Since the pulser is already running the first thing to be done in the
loop is to start an acquisition sequence of the digitizer by calling
digitizer_start_acquisition()
. This function only returns
when the digitizer is finished accumulating the requested number of
traces. When it is done we first fetch the area where the echo is
supposed to be by calling digitizer_get_area()
. The
function expects two arguments, the channel used for measuring (here
channel 1, CH1
), and the handle for the window previously
defined. After storing the result in the first element of array
area
we call the function again to also get the off-signal
area.
The next thing to be done is to display the area, or to be precise,
the difference between the on-signal and the off-signal areas,
multiplied by 1.0e12 because in the call of init_1d()
we
promised to display the signal in units of mV times ns, but the
digitizer returns the areas always in Vs units. Afterwards we have to
increment the counter I
to be prepared for displaying the next
data point.
We also need to write the data to a file, which is done by the next
call of fsave()
. Here we write first the current field,
both areas and the difference between the areas to a file. Since we
didn't open a file explicitely by a call of e.g.
get_file()
we don't have a file handle to pass to the
function as the first argument as we did in the first script. Instead
we simply leave out the file handle. In this case the first time the
script needs to write to the file a file selector box pops up.
All left to be done in the loop of the experiemnt is to sweep up the
field. The new field value as returned by
magnet_sweep_up()
is stored in the field
variable.
which then is used at the begin of the loop to figure out if the
experiment has to continue or if the end field has already been
reached.
This document was generated by Jens Thoms Toerring on September 6, 2017 using texi2html 1.82.