Pulse shaping

This user guide explains EasySpin's capabilities regarding shaped pulses, i.e. pulses with shapes other than rectangular monochromatic. Although EasySpin does currently not have the capability to simulate pulse EPR spectra obtained with sequences containing shaped pulses, EasySpin can calculate a wide range of pulse shapes, up- and downconvert them, calculate the associated excitation profiles and adapt the frequency and amplitude modulation functions to compensate for effects of the resonator transfer function and transmitter nonlinearity. The corresponding functionality is provided by the functions pulse, rfmixer, exciteprofile, resonator, and transmitter.

In the following, we go over the following topics:

Pulse shapes

EasySpin provides a range of shaped pulses through the function pulse. The parameters that define the pulse shape are supplied in a structure. Here is the most basic example

Par.tp = 0.100;  % µs
Par.Type = 'rectangular/none';
[t,IQ] = pulse(Par);

This will calculate the shape of a simple monochromatic rectangular pulse. Par.tp contains the pulse length, in microseconds. Par.Type is a character array specifying the type of pulse shape, with the amplitude modulation (AM) function given before the slash (/), and the frequency modulation (FM) function after it. Here, 'rectangular' for the AM specifies a simple rectangular shape, and 'none' for the FM specifies that there is no frequency modulation, i.e. the pulse is monochromatic.

pulse returns two things, the time axis and the IQ modulation data. The time axis is in microseconds and goes from 0 to Par.tp. The number of points is chosen automatically to accommodate the AM and FM without aliasing, but you can override this and specify the time step in Par.TimeStep. IQ is a complex vector that contains the in-phase (I) and quadrature (Q) signals needed to drive an IQ mixer to generate the final pulse shape at microwave frequencies. I is the real part of IQ, and Q is the imaginary part.

The overall pulse amplitude (in MHz) can be given in Par.Amplitude. Alternatively, you can give the nominal flip angle in Par.Flip, in radians. This value is converted to an amplitude as described in the documentation for pulse. If neither an amplitude nor a flip angle is given, the function assumes a flip angle of pi by default.

If pulse is called without requesting outputs, then the pulse shape is plotted, including the AM and FM functions and the excitation profile:

pulse(Par);    % plots the pulse shape and excitation profile

Many different AM and FM functions are implemented and can be combined arbitrarily. For example, a standard hyperbolic secant pulse can be obtained with

Par.tp = 0.100;  % µs
Par.Type = 'sech/tanh';
Par.Frequency = [-50 50];  % MHz
Par.beta = 5;
pulse(Par);

Here, the AM function is sech, and the FM function is tanh. Par.Frequency contains the start and end frequency of the frequency sweep, -50 and +50 MHz in this case. To fully define the AM and FM functions, the truncation parameter beta is necessary. Different AM and FM functions require different additional parameters, which can be found in the documentation of the pulse function.

To generate a chirp pulse with a linear frequency downsweep and a WURST amplitude profile, use the following:

Par.tp = 0.200;  % µs
Par.Type = 'WURST/linear';
Par.Frequency = [80 20]; % MHz
Par.nwurst = 10;
[t,IQ] = pulse(Par);

In Par.Frequency, the start frequency is higher than the end frequency. Therefore, a down-sweep will be generated. The WURST amplitude envelope also needs an additional parameter, nwurst.

It is possible to combine two AM functions. For example,

Par.tp = 0.200;  % µs
Par.Type = 'WURST*sech/linear';
Par.Frequency = [0 60];
Par.nwurst = 10;
Par.beta = 5;
pulse(Par);

generates a pulse shape with an AM that is the product of a WURST and a sech amplitude profile.

The pulse phase can be set in Par.Phase, in radians.

The function can also incorporate bandwidth compensation for resonators. For this, you need to provide the resonator transfer function and the corresponding frequency axis in Par.FrequencyResponse, as well as the microwave frequency in Par.mwFreq (see below for details).

Up- and downconversion

The pulse shape IQ data generated by pulse do not constitute the pulse shape as it is applied to the spins in a sample. For this purpose, the IQ data have to be used to modulate a microwave source, using IQ modulation. EasySpin provides the function rfmixer for this purpose. Say you have IQ data for a shaped pulse

Par.tp = 0.200;  % µs
Par.Type = 'WURST/linear';
Par.Frequency = [-50 50];
Par.nwurst = 10;
[tIQ,IQ] = pulse(Par);

Now you can feed these IQ data into rfmixer, together with a microwave LO (local oscillator) frequency, to get the actual microwave pulse.

mwFreq = 3; % GHz
[t,V] = rfmixer(tIQ,IQ,mwFreq,'IQmod');

The last input 'IQmod' tells the function to perform IQ modulation, that's what is needed to convert IQ data to a microwave signal. rfmixer supports many other modes, including IQ demodulation ('IQdemod'; modelling a quadrature mixture as typically used in a pulse EPR detector), single-sideband up- and down-conversion ('USB', 'LSB'), etc.

rfmixer can take a series of options in a optional structure. The most important one is the time step, in Opt.dt:

Opt.dt = 0.0001; % µs
[t,V] = rfmixer(tIQ,IQ,mwFreq,'IQmod',Opt);

If it is not given, a time step appropriate for the microwave frequency and the input data is determined automatically.

Excitation profiles

You can calculate the excitation profile of a pulse of arbitrary shape using EasySpin's function exciteprofile. At minimum, it requires the time axis t and the IQ data IQ as inputs. Let's take a WURST pulse with a linear frequency sweep:

Par.tp = 0.100;  % µs
Par.Type = 'WURST/linear';
Par.Frequency = [0 100];
Par.nwurst = 20;
[t,IQ] = pulse(Par);

The output from pulse can be fed directly into exciteprofile:

exciteprofile(t,IQ);

This will plot the excitation profile, showing the x, y and z components of the magnetic moment after the pulse, as a function of frequency offset. This is the actual excitation profile of the pulse, calculated using quantum dynamics, and not just the Fourier transform of the pulse shape (which is a decent approximation only for small flip angles).

To obtain the excitation profile, ask exciteprofile for outputs:

[offsets,M] = exciteprofile(t,IQ);

M contains the x, y, and z components of the magnetic moments, one per row. offsets is a vector of frequency offsets, in MHz. You can use this to plot the excitation profile:

Mz = M(3,:);  % z component
plot(offsets,Mz);
Resonator distortion and compensation

The ideal pulse shapes provided by pulse generally differ from the pulses experienced by the spins in the sample due to phase and amplitude distortions caused by the resonator transfer function (limited bandwidth of the resonator). The functions resonator and pulse can be used to simulate these effects or to adapt the pulses to compensate for them.

The effect of the resonator transfer function on a pulse can be modelled using the resonator function with the 'simulate' option. First, the ideal pulse shape is calculated using pulse and then fed into resonator with additional information on the resonator properties:

ResFreq = 9.50; % resonator center frequency, GHz
ResQL = 300; % resonator loaded Q-value
mwFreq = 9.49; % GHz

[t_distorted,signal_distorted] = resonator(t_ideal,signal_ideal,mwFreq,ResFreq,ResQL,'simulate');

To adapt the pulse shape to compensate for this distortion, use the option 'compensate':

[t_compensated,signal_compensated] = resonator(t_ideal,signal_ideal,mwFreq,ResFreq,ResQL,'compensate');

If an experimental resonator transfer function has been determined, this can be used in resonator by supplying the corresponding frequency axis and the transfer function instead of the resonator center frequency and loaded Q-value.

In the case of frequency-swept pulses, the sweep rate can be adapted to account for the resonator bandwidth limitations and achieve offset-independent adiabaticity. This sweep rate adaptation is implemented within pulse. In addition to defining the pulse properties, the microwave center frequency of the pulse needs to be defined in Par.mwFreq and the resonator profile and corresponding frequency axis need to be supplied in Par.FrequencyResponse:

Par.Type = 'sech/tanh';
Par.tp = 0.200;  % µs
Par.Frequency = [-80 80];  % MHz
Par.beta = 8; 

Par.mwFreq = 33.85;  % GHz
Par.FrequencyResponse = [nu; resonatorprofile];

pulse(Par);
Transmitter distortion and compensation

In addition to the resonator, another source of non-linear distortions is the transmitter, mostly the high-power amplifier. Often, the amplifier is driven in partial saturation. In this case, its output power is not a linear function of the input power.

The transmitter function allows to simulate the effect of this distortion on a pulse shape, and also to compensate a pulse shape to account for this. In either case, you need to provide the power transfer curve that maps the input amplitude (Ain) to the output amplitude (Aout). To simulate the effect, provide the pulse shape input signal and use the 'simulate' option. Be careful to properly scale the input signal so it is within the range of Ain.

[t,signal_ideal] = pulse(Par); % generate an ideal pulse shape

signal_distorted = transmitter(signal_ideal,Ain,Aout,'simulate');

To compensate for the distortion, provide the desired output signal (ideal pulse) on the scale of the output signal amplitudes (Aout in the example below) and use the 'compensate' option:

[t,signal_ideal] = pulse(Par); % generate an ideal pulse shape

signal_compensated = transmitter(signal_ideal*max(Aout)/Par.Amplitude,Ain,Aout,'compensate');

This will return an amplitude-compensated signal.

Additional details can be found in the reference page of transmitter and in the Examples.