Pulseq Sequence Interpreter#
The pulseq sequence interpreter consists of two sub-components. The SequenceProvider reads all the events from a pulseq sequence and calculates RF and gradient waveform. The unrolled pulse sequence is provided as UnrolledSequence which contains the unrolled waveforms and some additional data.
See also
User guide on the sequence calculation.
Sequence Provider#
Sequence provider class.
- class console.pulseq_interpreter.sequence_provider.SequenceProvider(gradient_efficiency: list[float], gpa_gain: list[float], high_impedance: list[bool], output_limits: list[int] | None = None, spcm_dwell_time: float = 5e-08, rf_to_mvolt: float = 1, system: ~pypulseq.opts.Opts = <pypulseq.opts.Opts object>)[source]#
Bases:
Sequence
Sequence provider class.
This object is inherited from pulseq sequence object, so that all methods of the pypulseq
Sequence
object can be accessed.The main functionality of the
SequenceProvider
is to unroll a given pulseq sequence. Usually the first step is to read a sequence file. The unrolling step can be achieved using theunroll_sequence()
function.Example
>>> seq = SequenceProvider() >>> seq.read("./seq_file.seq") >>> sqnc, gate, total_samples = seq.unroll_sequence()
- calculate_gradient(block: SimpleNamespace, fov_scaling: float, offset: float | int) ndarray [source]#
Calculate spectrum-card sample points of a pypulseq gradient block event.
- Parameters:
block – Gradient block from pypulseq sequence, type must be grad or trap
unroll_arr – Section of numpy array which will contain the unrolled gradient event
fov_scaling – Scaling factor to adjust the FoV. Factor is applied to the whole gradient waveform, excepton the amplitude offset.
- Return type:
Array with sample points of RF waveform as int16 values
- Raises:
ValueError – Invalid block type (must be either
grad
ortrap
), gradient amplitude exceeds channel maximum output level
- calculate_rf(block: SimpleNamespace, b1_scaling: float) tuple[ndarray, ndarray] [source]#
Calculate RF sample points to be played by TX card.
- Parameters:
block – Pulseq RF block
unroll_arr – Section of numpy array which will contain unrolled RF event
b1_scaling – Experiment dependent scaling factor of the RF amplitude
unblanking – Unblanking signal which is updated in-place for the calculated RF event
- Return type:
List with the RF pulse in the first element, and the unblanking signal in the second element
- Raises:
ValueError – Invalid RF block
- from_pypulseq(seq: Sequence) None [source]#
Cast a pypulseq
Sequence
instance to thisSequenceProvider
.If argument is a valid
Sequence
instance, all the attributes ofSequence
are set in thisSequenceProvider
(inherits fromSequence
).- Parameters:
seq – Pypulseq
Sequence
instance- Raises:
ValueError – seq is not a valid pypulseq
Sequence
instanceAttributeError – Key of Sequence instance not
- get_adc_events() list [source]#
Extract ADC ‘waveforms’ from the sequence.
TODO: Add error checks
- Returns:
list
- Return type:
List of with waveform ID, gate signal and reference signal for each unique ADC event.
- get_rf_events() list [source]#
Extract RF ‘waveforms’ from sequence file.
- Returns:
list
- Return type:
list of unique RF events.
- plot_unrolled(time_range: tuple[float, float] = (0, -1)) tuple[Figure, ndarray] [source]#
Plot unrolled waveforms for replay.
- Parameters:
time_range – Specify the time range of the plot in seconds. If the second value is smaller then the first or -1, the whole sequence is plotted.
(0 (default =) – Specify the time range of the plot in seconds. If the second value is smaller then the first or -1, the whole sequence is plotted.
-1) – Specify the time range of the plot in seconds. If the second value is smaller then the first or -1, the whole sequence is plotted.
- Return type:
Matplotlib figure and axis
- unroll_sequence(parameter: AcquisitionParameter) UnrolledSequence [source]#
Unroll the pypulseq sequence description.
TODO: Update this docstring
- Parameters:
larmor_freq – (Larmor) frequency of the carrier RF waveform
b1_scaling – Factor for the RF waveform, which is to be calibrated per coil and phantom (load), by default 1.0
optional – Factor for the RF waveform, which is to be calibrated per coil and phantom (load), by default 1.0
fov_scaling – Per channel factor for the gradient waveforms to scale the field of fiew (FOV), by default Dimensions(1.0, 1.0, 1.0)
optional – Per channel factor for the gradient waveforms to scale the field of fiew (FOV), by default Dimensions(1.0, 1.0, 1.0)
- Returns:
Instance of an unrolled sequence object which contains a list of numpy arrays with the block-wise calculated sample points in correct spectrum card order (Fortran).
The list of unrolled sequence arrays is returned as uint16 values which contain a digital signal encoded by 15th bit. Only the RF channel does not contain a digital signal. In addition, the adc and unblanking signals are returned as list of numpy arrays in the unrolled sequence instance.
- Return type:
- Raises:
ValueError – Larmor frequency too large
ValueError – No block events defined
ValueError – Sequence timing check failed
ValueError – Amplitude limits not provided
Examples
For channels ch0, ch1, ch2, ch3, data values n = 0, 1, …, N are ordered the following way.
>>> data = [ch0_0, ch1_0, ch2_0, ch3_0, ch0_1, ch1_1, ..., ch0_n, ..., ch3_N]
Per channel data can be extracted by the following code.
>>> rf = seq[0::4] >>> gx = (seq[1::4] << 1).astype(np.int16) >>> gy = (seq[2::4] << 1).astype(np.int16) >>> gz = (seq[3::4] << 1).astype(np.int16)
All the gradient channels contain a digital signal encoded by the 15th bit. - gx: ADC gate signal - gy: Reference signal for phase correction - gz: RF unblanking signal The following example shows, how to extract the digital signals
>>> adc_gate = seq[1::4].astype(np.uint16) >> 15 >>> reference = seq[2::4].astype(np.uint16) >> 15 >>> unblanking = seq[3::4].astype(np.uint16) >> 15
As the 15th bit is not encoding the sign (as usual for int16), the values are casted to uint16 before shifting.
Unrolled Sequence#
Interface class for an unrolled sequence.
- class console.interfaces.unrolled_sequence.UnrolledSequence(seq: ndarray, sample_count: int, gpa_gain: list[float], gradient_efficiency: list[float], rf_to_mvolt: float, dwell_time: float, duration: float, adc_count: int, parameter: AcquisitionParameter)[source]#
Bases:
object
Unrolled sequence interface.
This interface is used to share the unrolled sequence between the different components like TxEngine, SequenceProvider and AcquisitionControl. An unrolled sequence is generated by a SequenceProvider() instance using the unroll_sequence function.
- adc_count: int#
Number of adc events in the sequence.
- duration: float#
Total duration of the unrolled sequence in s.
- dwell_time: float#
Dwell time of the spectrum card replay data (unrolled sequence). Defines the distance in time between to sample points. Note that this dwell time does not correlate to the larmor frequecy. Due to the sampling theorem dwell_time < 1/(2*larmor_frequency) must be satisfied. Usually a higher factor is chosen.
- gpa_gain: list[float]#
The gradient waveforms in pulseq are defined in Hz/m. The translation to mV is calculated by 1e3 / (gyro * gpa_gain * grad_efficiency). The gpa gain is given in V/A and accounts for the voltage required to generate an output of 1A. The gyromagnetic ratio defined by 42.58e6 MHz/T.
- gradient_efficiency: list[float]#
The gradient waveforms in pulseq are defined in Hz/m. The translation to mV is calculated by 1e3 / (gyro * gpa_gain * grad_efficiency). The gradient efficiency is given in mT/m/A and accounts for the gradient field which is generated per 1A. The gyromagnetic ratio defined by 42.58e6 MHz/T.
- parameter: AcquisitionParameter#
Hash of acquisition parameters used to calculate the sequence.
- rf_to_mvolt: float#
If sequence values are given as float values, they can be interpreted as output voltage [mV] directly. This conversion factor represents the scaling from original pulseq RF values [Hz] to card output voltage.
- sample_count: int#
Total number of samples per channel.
- seq: ndarray#
Replay data as int16 values in a list of numpy arrays. The sequence data already contains the digital adc and unblanking signals in the channels gx and gy.