Back: 8.2 Defining Pulses Forward: 8.3.1 Simplified pulse cycling   FastBack: 8. Using Pulsers Up: 8. Using Pulsers FastForward: 9. Example EDL Scripts         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

8.3 Using Pulses

When pulses have been defined and the experiment is started (indicated by the begin of the EXPERIMENT section) all pulses get set (as long as their lengths are defined and non-zero) and all channels or PODs that have been assigned pulses (that are really used during the experiment) are switched on.

There are two methods to change the properties of pulses. The first one works by calling a dedicated function. To change the start position of, for example, pulse 1 by the start position change time (DELTA_START) as defined in the properties of the pulse the function pulser_shift() can be used:

 
pulser_shift( P1 );      // or  pulser_shift( 1 );

Also the start position of several pulses at once can be changed because this function also accepts a (comma separated) list of pulses. If the function is called with no arguments at all the start positions of all pulses that have the DELTA_START property defined are changed.

There is a similar function for changing the length of pulses by their DELTA_LENGTH, called pulser_increment():

 
pulser_increment( P3 );  // or  pulser_increment( 3 );

As for the pulser_shift() function also this functions accepts a comma separated list of pulses, and calling it with no arguments automatically lengthens all pulses that have the DELTA_LENGTH property defined.

The second method allows to you to change the start position or length of a pulse directly and in increments differing from DELTA_START or DELTA_LENGTH. If, for example, the position of pulse 4 has to be changed to 500 ns and its length to 120 ns, one may simply write

 
P4.START  = 500 ns;
P4.LENGTH = 120 ns;

This method can also be used to switch off a pulse completely by assigning 0 to the pulse length.

Of course, as in the definition of the pulses in the PREPARATION section the properties of the pulse itself and other pulses can be used in setting the new values, e.g.:

 
P4.START  = P3.START + 200 ns;
P4.LENGTH = 2 * P4.LENGTH + 20 ns;

As you see, these properties (i.e. start positions and lengths and the corresponding delta start positions and lengths) of pulses can be treated nearly as if they are just normal variables.

Also the values for DELTA_START and DELTA_LENGTH can be changed in this way at any time during the experiment:

 
P4.DELTA_START  = 20 ns;
P4.DELTA_LENGTH = 10 ns;

This holds even if these properties haven't been defined in the PREPARATION section at all.

The only pulse properties that may not be changed during the experiment are the function and the phase sequence associated with the pulse.

There is only one point that needs to be taken care of: Just calling one of these methods to change pulse properties does not change the real pulses immediately. Instead, all these changes are stored internally in the program. The changes only get send to the pulser when the function pulser_update() is called. Therefor, the normal way to change the pulse pattern is to change all necessary pulse properties and when everything is done to call pulser_update() in order to commit the changes. In this moment the program will also do all its usual checks, e.g. it will test that no pulses overlap.

There is a further function that resets all pulses to their initial state, pulser_pulse_reset(). This function can, for example, be used for repeating the same experiment several times without having to reset each pulse individually. As in the other functions the argument can be either one pulse, a list of pulses or no argument, in which case all pulses are reset to their initial positions and lengths (i.e. as set in the initial definition of the pulse in the PREPARATIONS section.

Here is now a somewhat shortened example of a 2 pulse Hahn-echo experiment. Two microwave pulses are needed, a pi-half and a pi pulse, plus a detection pulse to trigger the digitizer. This trigger pulse must move twice as fast as the second microwave pulse because the distance of the echo from the second pulse is always as large as the distance between both the microwave pulses.

 
DEVICES:

dg2020_b;    // Berlin X-band spectrometer pulser
tds520c;     // digitizer

VARIABLES:

tau_0     = 200 ns;
delta_tau =  50 ns;
pi_pulse  = 100 ns;

I, J;
data[ 20, 1024];
Window;

ASSIGNMENTS:

TIMEBASE:     5 ns;
TRIGGER_MODE: INTERNAL, REPEAT_TIME = 20 ms;
MICROWAVE:    POD = P8,  V_HIGH = 5 V, V_LOW = 0 V;
DETECTION:    POD = P5,  V_HIGH = 3 V, V_LOW = 0 V;

PREPARATIONS:

P0:   FUNCTION    = MICROWAVE,       // 1st microwave pulse
      START       = 0 ns,
      LENGTH      = pi_pulse / 2;

P1:   FUNCTION    = MICROWAVE,       // 2nd microwave pulse
      LENGTH      = pi_pulse,
      START       = P0.START + P0.LENGTH / 2 + tau_0 - P1.LENGTH / 2,
      DELTA_START = delta_tau;

P2:   FUNCTION    = DETECTION,       // trigger pulse
      LENGTH      = 5 ns,
      START       = P1.START + P1.LENGTH / 2 + tau_0,
      DELTA_START = 2 * delta_tau;

Window = digitizer_define_window( P2.START + 250 ns, 100 ns );

EXPERIMENT:

FOR J = 1 : 20 {          // repeat experiment 20 times
    FOR I = 1 : 1024 {
        digitizer_start_acquisition( );
        data[ J, I ] = digitizer_get_area( CH1, Window );
        pulser_shift( );             // move all pulses
        pulser_update( );            // commit the changes
    }
    pulser_pulse_reset( );           // reset all pulses
}

Beside the functions for changing the positions and lengths of pulses there are also functions to adjust the phases of pulses, needed for for phase cycled experiments. When the experiment starts the phase of a pulse is set to the first phase of its associated phase sequence (defined in the PHASES section). To switch to the next phase the function pulser_next_phase() has to be used. In contrast to the functions pulser_shift() and pulser_increment() this function can not be used for phase changes of individual pulses but alway applies to all pulses that have been assigned a phase sequence. Thus this function does not accepts any arguments.

Again, the necessary changes are only send to the pulser when the function pulser_update() is called afterwards. By repeatedly invoking pulser_next_phase() one can run through the complete phase sequence. To reset all pulses to their start phase (i.e. the first phase of the associated phase sequence) the function pulser_phase_reset() can be used.

The next (rather simplified) example is a script for a phase cycled (1-dimensional) stimulated echo experiment. We need three microwave pulses and a further detection pulse that triggers the digitizer at the right moment. During the experiment the first two microwave pulses have to be phase cycled.

 
DEVICES:

dg2020_b;             // Berlin X-band spectrometer pulser
tds520c;              // digitizer

VARIABLES:

tau_0     = 250 ns;   // start distance between 1st & 2nd pulse
delta_tau =  25 ns;   // and the change of this distance
t_0       = 400 ns;   // start distance between 2nd & 3rd pulse
delta_t   =  50 ns;   // and the change of this distance

Curve_length = 128;   // number of points of curve

area, data;
I, J;

ASSIGNMENTS:

TIMEBASE:     5 ns;
TRIGGER_MODE: INTERNAL, REP_FREQ = 200 Hz;

MW:           POD = P1, P2, P3, P4, INVERTED, V_HIGH = 5 V, V_LOW = 0 V;
DETECTION:    POD = P0,                       V_HIGH = 5 V, V_LOW = 0 V;
      
       
PHASE_SETUP:  MW,            // cycle microwave channel
              +X: POD = P1,  // POD 1 on for +X
              -X: POD = P2,  // POD 2 on for -X
              +Y: POD = P3,  // POD 3 on for +Y
              -Y: POD = P4;  // POD 4 on for -Y

PHASES:

PHASE_SEQUENCE_0 = +x, -x, +x, -x;  // for 1st pulse
PHASE_SEQUENCE_1 = +x, +x, -x, -x;  // for 2nd pulse

PREPARATIONS:

P0:  FUNCTION    = MW,                        // 1st microwave pulse
     START       = 0 ns,
     LENGTH      = pi_half_pulse_length,
     PHASE_CYCLE = PHASE_SEQUENCE_0;
     
P1:  FUNCTION    = MW,                        // 2nd microwave pulse
     START       = P0.START + P0.LENGTH  + tau0,
     LENGTH      = pi_half_pulse_length,
     PHASE_CYCLE = PHASE_SEQUENCE_1;

P2:  FUNCTION    = MW,                        // 3rd microwave pulse
     START       = P1.START + P1.LENGTH + t0,
     LENGTH      = pi_half_pulse_length,
     DELTA_START = delta_t;

P3:  FUNCTION    = DETECTION,                 // digitizer trigger pulse
     START       = P2.START + P2.LENGTH,
     LENGTH      = 10 ns,
     DELTA_START = delta_t;

Window = digitizer_define_window( P3.START + 250 ns, 100 ns );
init_1d( );


EXPERIMENT:

FOR I = 1: Curve_length {
    data = 0.0;
    FOR J = 1 : 4 {
        digitizer_start_acquisition( );
        area = digitizer_get_area( CH1, Window );

        IF J == 1 OR J == 4 {
            data += area;     // add 1st & 4th area
        } ELSE {
            data -= area;     // subtract 2nd & 3rd area
        }

        pulser_next_phase( );
        pulser_update( );
    }

    display( I, data );
    pulser_shift( );
    pulser_update( );
}

Back: 8.3 Using Pulses Forward: 9. Example EDL Scripts   FastBack: 8. Using Pulsers Up: 8.3 Using Pulses FastForward: 9. Example EDL Scripts         Top: fsc2 Contents: Table of Contents Index: Index About: About This Document

8.3.1 Simplified pulse cycling

The inner loop in the previous example runs through the 4 different phase settings, adding up the areas with the correct sign. Instead of writing out this loop one could also define an acquisition sequence and use the EDL function get_phase_cycled_area(). This function does everything automatically that had to be spelled out explicitely in the loop in the previous example and thus makes the script much simpler. The only changes needed are in the PHASES and EXPERIMENT section: first, an acquisition sequence must be defined and, second, the whole inner loop can be replaced by a single function call.

 
PHASES:

PHASE_SEQUENCE_0     = +x, -x, +x, -x;  // for 1st pulse
PHASE_SEQUENCE_1     = +x, +x, -x, -x;  // for 2nd pulse
ACQUISITION_SEQUENCE =  +,  -,  -,  +;

...

Window = digitizer_define_window( P3.START + 250 ns, 100 ns );

EXPERIMENT:

FOR I = 1: 128 {
    data = get_phase_cycled_area( CH1, Window );
    display( I, data );
    pulser_shift( );
    pulser_update( );
}

As can be seen from this example get_phase_cycled_area() not only sets the pulse phases but also starts the digitizer acquisition, fetches the measured areas from the digitizer and adds up the areas according to the acquisition sequence.

get_phase_cycled_area() can handle one as well as two acquisition sequences, see below. But also a single acquisition sequence may need data from two different digitizer channels, for example an acquisition sequence like this:

 
ACQUISITION_SEQUENCE =  +A, -B, -A, +B;

which means that the value for the first phase setting has to be fetched from the first digitizer channel (associated with A) and that for the second phase setting the value from the second digitizer channel (associated with B) has to be subtracted, etc. In this case get_phase_cycled_area() expects its second argument to be the second digitizer channel, i.e. it must be called like this:

 
data = get_phase_cycled_area( CH1, CH2, Window );

In some cases one might be interested not only in the value from just one digitizer window but from two or more. Thus you may specify, following the digitizer channel(s) to be used for fetching data as many windows as you need. For each of the windows the phase cycled area is measured. Of course, in these cases not just one data value will be returned but an array of data values with as many elements as there are digitizer windows passed to the function. It is the responsibility of the writer of the EDL script to supply an array long enough to hold exactly as many data as returned by the function. Here's an example:

 
VARIABLES:

Window_1, Window_2;
I;
data[ 2 ];

PHASES:

PHASE_SEQUENCE_0     = +x, -x, +x, -x;  // for 1st pulse
PHASE_SEQUENCE_1     = +x, +x, -x, -x;  // for 2nd pulse
ACQUISITION_SEQUENCE = +A, -B, -A, +B;

...

Window_1 = digitizer_define_window( P3.START + 250 ns, 100 ns );
Window_2 = digitizer_define_window( P3.START + 650 ns );

EXPERIMENT:

FOR I = 1: 128 {
    data = get_phase_cycled_area( CH1, CH2, Window_1, Window_2 );
    display( I, data[ 1 ], 1, I, data[ 2 ], 2 );
    pulser_shift( );
    pulser_update( );
}

Finally, if there are two acquisition sequences get_phase_cycled_area() will return 2 values for each digitizer window. Thus it will returns an array of values, where the first two values are the data from both the acquisition sequences of the first window, the next two from the second window etc.


Back: 8.3 Using Pulses Forward: 9. Example EDL Scripts   FastBack: 8. Using Pulsers Up: 8.3 Using Pulses FastForward: 9. Example EDL Scripts

This document was generated by Jens Thoms Toerring on September 6, 2017 using texi2html 1.82.