Sequences#

Device-agnostic description of an acquisition, shared by the interpreter, the estimators and the sequence optimizer. A description is a list of events with the timing and the tissue interaction each one carries; nothing in it names a vendor or a device.

This page is the description and what it is assembled from. Writing a simulator out of these is on Signal models, running one is on Running a simulation, and the temporal basis a run spans is on Model-based reconstruction.

Operators#

The modules a sequence is assembled from. An operator is a Python function returning the events it plays and how long it holds the timeline, and @ composes two into one – so a preparation or a readout TorchSim does not ship reaches the fused kernels with no change to them.

The five readouts differ only in what they play around the sample, which is what separates a spoiled, an unbalanced, a balanced and a refocused train. SampledPulse() plays a waveform as one hard pulse per sample, with relaxation, precession and exchange between samples, for a pulse whose duration matters to the signal.

Operator

One module of a sequence: what it plays, and how long it lasts.

Excitation

Return a pulse that tips magnetization into the transverse plane.

Refocusing

Return a pulse the sequence sits between crushers, unless told otherwise.

Inversion

Return an ideal inversion, scaled by the tissue's inversion efficiency.

Saturation

Return an off-resonance pulse that deposits power in a semisolid pool.

SampledPulse

Return a pulse played as one hard pulse per sample, with free precession between.

Readout

Return one sample of the transverse magnetization, demodulated by a phase.

Delay

Return time passing, and whatever the sequence plays across it.

Dephase

Return an unbalanced gradient, taking no time to play.

Spoil

Return ideal transverse spoiling, taking no time to play.

bSSFPReadout

Return a sample the repetition rewinds after.

SSFPFidReadout

Return a sample followed by one unbalanced gradient.

SSFPEchoReadout

Return one unbalanced gradient, then the sample the echo forms at.

SPGRReadout

Return a sample followed by ideal transverse spoiling.

FSEReadout

Return the sample at a spin echo, marked as the echo centre.

Pulses and shims#

An ideal pulse turns the whole voxel through one angle. rf_definition() takes a complex envelope instead – one row per transmit channel – so a selective excitation is integrated over the slice rather than scaled, and ShimDefinition gives the amplitude and phase each channel is driven at. A simulator takes them as pulse= and shims=.

compose_spinor() is the rotation a shaped pulse leaves on each spin, composed sample by sample in torch so that derivatives reach the samples: how a pulse’s own samples are designed rather than chosen.

rf_definition

Return the definition of a pulse from the envelope a scanner plays.

ShimDefinition

One transmit-shim definition: a complex weight per channel.

compose_spinor

The Cayley-Klein pair a shaped pulse leaves, sample by sample.

Description#

The event stream itself: what a layout composes to, and what a sequence arriving from a scanner is read into. SequenceDescription.from_operators() builds one directly, SequenceDescription.from_pulseq() reads one out of a Pulseq .seq file or a sequence a design holds in memory, and from_description() runs either.

Reading a .seq file needs pypulseq, which parses the format and computes the gradient trajectory the echo is found on: pip install torchsim[pulseq]. Nothing else in the package imports it.

SequenceDescription

Event stream and RF resources for one sequence or subsequence.