NMR Programming

Qubi can be written the way a pulse programme is written on a spectrometer: pulses with flip angles and phases, delays in seconds, and scalar couplings in hertz. The NMR standard library turns those into ordinary rotations, so every NMR program is also a circuit, and the NMR Analysis tab turns the circuit back into a pulse programme, a spectrum and a set of Bloch vectors.

The model

A liquid-state NMR quantum computer stores each qubit in a spin-½ nucleus of one molecule. In the rotating frame of each isotope three things happen to a spin:

  • Pulses rotate it about an axis in the transverse plane. A pulse of θ degrees about x is RX by θ/180 in Qubi's multiples of π.
  • Free precession rotates it about z at its offset from the carrier, Δν hertz, for t seconds: RZ by 2Δνt.
  • Scalar coupling to a partner spin evolves the pair under 2πJ IzSz for t seconds: CX, RZ by Jt, CX.

Every gate of the circuit model has such a translation, which is how the NMR Analysis tab draws a pulse programme for any circuit. The library functions below let you write the programme directly.

The NMR library

FunctionWhat it doesPage
Pulse(angle, phase, ...)Rotate the listed spins by angle degrees about x, y, -x or -y.Pulse
PulsePhase(angle, phi, ...)The same about the transverse axis at phi degrees from x.PulsePhase
Delay(t, offset, ...)Free precession for t seconds at offset hertz.Delay
JCouple(t, J, a, b)Scalar coupling evolution of one pair for t seconds.JCouple
SpinEcho(tau, offset, ...)90°x, τ, 180°y, τ: the Hahn echo.SpinEcho
CPMG(n, tau, offset, ...)90°x then n refocusing blocks.CPMG
INEPT(J, source, target)Polarisation transfer through the coupling.INEPT
Readout(...)The 90°y readout pulse before acquisition.Readout

The library lives in standard/NMR.qubi and is included by #include standard/all.qubi, the default prepended layer, so the functions are available in every file. Open the Functions palette or the Examples list under NMR to see them.

A first programme

#settings NmrSample "chloroform"
#settings NmrReadout "none"

// excite the proton, let it precess for 1 ms at 250 Hz, refocus with an echo
Pulse(90, "x", 0)
SpinEcho(0.001, 250, 0)
Readout(0)

Run it and open NMR Analysis. The pulse programme shows the 90° pulse, the two 1 ms delays and the refocusing pulse with their real lengths for the current B1. The spectrum shows the proton line of chloroform split by the carbon; the Bloch view shows the spin back where the echo put it.

Units, in one place

QuantityUnit in QubiNote
Flip angledegreesPulse(90, ...); the library converts to multiples of π.
Pulse phasex, y, -x, -y or degreesStrings for the four axes, a number of degrees for PulsePhase.
Delayseconds0.001 is one millisecond. Write small numbers with a decimal point.
OffsethertzResonance offset from the carrier; can be negative.
Coupling Jhertz215 for the one-bond ¹H-¹³C coupling of chloroform.
Chemical shiftppmSet on the NMR tab or in the sample, not in the programme.
Fieldtesla#settings NmrField 11.74; 500 MHz for protons.
A classical argument that happens to be a small whole number, such as an offset of 0, can be mistaken for a wire index when it is passed on to another function. The library wraps such arguments in (float); do the same in your own routines.

Where to go next