Skip to content

Pulseq MATLAB to Koma Translation Tables ​

Compact lookup tables for humans and LLMs translating MATLAB Pulseq code to Koma. For the block-construction syntax behind @addblock, see Build Sequences with @addblock. For a complete translated sequence, see Building and Exporting a Pulseq GRE Sequence.

Conventions ​

PulseDesigner make_* constructor inputs follow Pulseq units for plain numbers. That is the external sequence-design API. Koma event objects and Scanner fields store physical SI values internally, so accessors such as area(g) return SI even when the constructor input matched Pulseq.

Unitful is per argument, not per call. The same constructor call can mix Unitful quantities, plain Pulseq numerics, and dimensionless options.

julia
gx = make_trapezoid(; flat_area=Nx / FOV, flat_time=6.4u"ms", sys)

rf, gz, gzr = make_sinc_pulse(
    90u"deg"; duration=3u"ms", slice_thickness=thickness,
    time_bw_product=4, apodization=0.5, sys,
)

Sequence setup ​

matlab
addpath(genpath('path/to/pulseq/matlab'))  % Import Pulseq

sys = mr.opts( ...                         % Define scanner
    'MaxGrad', 32, 'GradUnit', 'mT/m', ...
    'MaxSlew', 130, 'SlewUnit', 'T/m/s', ...
    'rfRingdownTime', 30e-6, ...
    'rfDeadTime', 100e-6, ...
    'adcDeadTime', 10e-6);

seq = mr.Sequence(sys)                     % Create sequence
seq.setDefinition('FOV', [fov fov dz])     % Set definition
seq.write('seq.seq')                       % Write file

Blocks and axes ​

matlab
seq.addBlock(rf, gz)
seq.addBlock(gx, adc)
seq.addBlock(gxPre, gyPre, gzReph)
seq.addBlock(mr.makeLabel('SET', 'LIN', ky))
seq.addBlock(gxPre, mr.scaleGrad(gyPre, peScale))
if hasAdc
    seq.addBlock(gx, adc)
else
    seq.addBlock(gx)
end

Timing helpers ​

Use sys when translating MATLAB formulas that depend on sample-edge, ring-down, dead-time, or block duration behavior.

matlab
ceil(t / raster) * raster             % Round up to raster
round(t / raster) * raster            % Round to raster

mr.calcDuration(rf)                   % RF duration
mr.calcDuration(adc)                  % ADC duration
mr.calcDuration(rf, gz)               % Block duration
mr.calcRfCenter(rf)                   % RF center
adc.dwell                             % ADC dwell

Trapezoidal gradients ​

Plain PulseDesigner gradient numerics use Pulseq units. Koma event accessors such as area(gx) return physical SI values.

matlab
fov = 0.22;
Nx = 64;
sliceThickness = 3e-3;
deltaK = 1/fov;
readoutTime = 6.4e-3;
preTime = 2e-3;
blipDuration = 0.5e-3;
testAmplitude = 10e3;
testRiseTime = 1e-3;
testFlatTime = 10e-3;

gx = mr.makeTrapezoid('x', 'FlatArea', Nx*deltaK, 'FlatTime', readoutTime, 'system', sys)
gxEpi = mr.makeTrapezoid('x', 'Amplitude', Nx*deltaK/readoutTime, 'FlatTime', readoutTime, 'system', sys)
gxPre = mr.makeTrapezoid('x', 'Area', -gx.area/2, 'Duration', preTime, 'system', sys)
gyBlip = mr.makeTrapezoid('y', 'Area', deltaK, 'Duration', blipDuration, 'system', sys)
gzSpoil = mr.makeTrapezoid('z', 'Area', 4/sliceThickness, 'system', sys)
gTest = mr.makeTrapezoid('x', 'Amplitude', testAmplitude, 'riseTime', testRiseTime, 'flatTime', testFlatTime, 'fallTime', 2*testRiseTime, 'system', sys)

Extended gradients and gradient sums ​

matlab
gyBlipUp = mr.makeExtendedTrapezoid('y', 'times', timesUp, 'amplitudes', ampsUp, 'system', sys)
gz180n = mr.makeExtendedTrapezoid('z', 'times', gz180Times, 'amplitudes', gz180Amps, 'system', sys)
[gzr1, times, amplitudes] = mr.makeExtendedTrapezoidArea('z', g0, g1, A, sys)
gSum = mr.addGradients({g1, g2}, sys)

RF pulses ​

matlab
rf = mr.makeBlockPulse(pi/2, 'Duration', 300e-6, 'system', sys)

[rf, gz, gzr] = mr.makeSincPulse(pi/2, 'Duration', 3e-3, 'SliceThickness', thickness, 'system', sys)
[rf, gz, gzr] = mr.makeSincPulse(pi/2, 'Duration', 3e-3, 'SliceThickness', thickness, 'apodization', 0.5, 'timeBwProduct', 4, 'system', sys)
rfInv = mr.makeSincPulse(pi, 'Duration', 10e-3, 'timeBwProduct', 8, 'system', sys)

[rfFat, ~, ~] = mr.makeGaussPulse(pi/2, 'Duration', 8e-3, 'Bandwidth', abs(fatOffset), 'freqOffset', fatOffset, 'system', sys)
[rf, ~, ~] = mr.makeArbitraryRf(rfSignal, flipAngle, 'Dwell', dwell, 'Delay', rfDelay, 'system', sys)
[rfSlr, gzSlr, gzrSlr] = mr.makeSLRpulse(pi/2, 'Duration', 3e-3, 'SliceThickness', thickness, 'system', sys)

ADC, delays, labels, and extensions ​

matlab
readoutTime = 6.4e-3;
adcDelay = gx.riseTime;
adcDwell = 4e-6;

adc = mr.makeAdc(Nx, 'Duration', readoutTime, 'Delay', adcDelay, 'system', sys)
adc = mr.makeAdc(adcSamples, 'Dwell', adcDwell, 'Delay', adcDelay, 'system', sys)

delayTE = mr.makeDelay(20e-3)
label = mr.makeLabel('SET', 'LIN', ky)
trig = mr.makeTrigger('physio1', 'duration', 2000e-6)
osc = mr.makeDigitalOutputPulse('osc0', 'duration', 100e-6)

rot = mr.makeRotation(phi)
seq.addBlock(mr.rotate('z', phi, gx), adc)

MATLAB parity tolerances ​

MATLAB SLR parity permits a 1 nT absolute tolerance only for the RF waveform because NumPy/PocketFFT and FFTW round spectral factorization differently. Gradients, timings, metadata, and all other constructors remain strict.

Not-yet-mapped Pulseq features ​

These Pulseq features are not direct PulseDesigner APIs or full parity paths yet. Keep them explicit in translations instead of hiding them behind one-off local wrappers.

Pulseq featureKoma status
mr.makeRfShim(...)RF shimming extension is not implemented in Pulseq read/write.
mr.makeSoftDelay(...)Soft-delay extension is not implemented in Pulseq read/write.
mr.addRamps(...)No ramp-optimization helper; port the final gradient waveform explicitly.
mr.traj2grad(...)No direct helper; derive the gradient waveform explicitly.
ADC phaseModulationKoma ADC stores one phase offset; ADC phase shapes are not strict parity yet.
mr.align(...)No direct clone helper; use explicit delays or block Duration(...).
mr.splitGradientAt(...)No public clone helper; rebuild the required pieces explicitly when needed.