Sequence#
Import: cmrseq.Sequence
- class Sequence(building_blocks, system_specs, snap_to_raster=False, copy=False)[source]#
Bases:
object
This class serves as a container for MRI-sequence building blocks.
All blocks contained in a sequence are kept as mutable objects of type SequenceBaseBlock or rather its subclasses. This means if a contained block is changed/transformed outside the sequence scope, these changes are also reflected in the sequence.
Below, the functionality provided by a cmrseq.Sequence object is explained according to the groups:
Instantiation and composition
Get contained blocks
Gridding, Moments and K-space
Instantiation and composition
To instantiate a Sequence you need a list containing building blocks and a sytem-specification definition. On instantiation, all blocks are validated against the system limits. If any block violates the limits, an exception is raised.
Adding blocks: Blocks or even entire sequences can be added to an existing sequence object one the obe hand by using the :code:’add_block’, :code:’append’, :code:’extend’ methods (see documentation). And on the other hand, the Sequence class implements the addition operator, which combines two sequence objects into either a new object containing copies of all blocks contained in the other two or by in-place addition where no copies are made:
new_sequence_object = sequence1 + sequence2 # Combination with copy sequence1 += sequence2 # inplace combination of seq2 into seq1
Unique names: a sequence objects keeps a mapping of automatically created unique names to the actual blocks. Whenever blocks are added
Get contained blocks
There are multiple ways to query single or even multiple blocks at once from the sequence object. To get a complete list of unique block-names use the property
seq.blocks
.Access by name: 1. Indexing by unique name:
seq["trapezoidal_0"]
2. Get all blocks by partial string match:seq.get_block(partial_string_match=...)
3. Get all blocks by matching regular expression on unique names:seq.get_block(regular_expression=...)
- Get a sequence object containing copies of all blocks matched as in (2. & 3.)
seq.partial_sequence(...)
Assuming temporal order of start 1. Indexing by integer:
seq[0]
2. Indexing by slice:seq[0:5]
3. Indexing by tuple of integers:seq[(0, 2, 5)]
4. Iterating over sequence:[block for block in seq]
5. Iterating over sequence with block-names{name: block for (name, block) in seq.items()}
Gridding, Moments and K-space
Gradients, RF and ADCs represented on a dense temporal grid defined by the system raster times can be obtained by calling the methods:
gradients_to_grid
,rf_to_grid
, andadc_to_grid
.- Gradient moments of specified order can be integrated using the function
seq.calculate_moment
.
To get a representation of the kspace-trajectory as well as timing and position of sampling events defined by contained ADC blocks can be obtained by the
seq.calculate_kspace
function.
- Parameters:
building_blocks (
List
[SequenceBaseBlock
]) – List of building Blockssystem_specs (
SystemSpec
) – Instance of SystemSpecsnap_to_raster (
bool
) –copy (
bool
) –
Methods:
adc_to_grid
([force_raster])Grids the ADC-Events of all blocks contained in the sequence as boolean 1D mask along with the resulting time-grid.
add_block
(block[, copy])Add the instance of block to the internal List of sequence blocks.
append
(other[, copy, end_time])If both system specifications match, copies all blocks from other, shifts them by the current end time of this sequence intance (plus an additional delay according to ADC/RF - dead times and RF-ring-down time) and adds the blocks to itself.
Evaluates the k-space trajectory of the sequence.
calculate_moment
([moment, center_time, ...])Calculates gradient moments about a given center point
Combines all ADC-type blocks contained in the sequence, on a joint time grid.
Combines the gradient definitions of all blocks contained in the sequence, into a joint single definition.
Combines the rf-definitions of all blocks contained in the sequence, into a joint single definition.
copy
()Returns deepcopy of the sequence object
extend
(other[, copy])If both system specifications match, copies all blocks from other shifts them by own tmax and adds the blocks to own collection
get_block
([block_name, ...])Returns reference to the block whose member name matches the specified argument.
gradients_to_grid
([start_time])Grids gradient definitions of all blocks contained in the sequence, on a joint time grid from the minimal to maximal value in single time-points definitions with a step-length defined in system_specs.grad_raster_time.
items
()Returns a generator yielding (unique_block_name, block) tuples
partial_sequence
(copy_blocks[, ...])Returns a cmrseq.Sequence object containing references or deep-copies of all blocks matched either with partial-string-match or regular expressions specified as keyword argument.
register_omatrix
(matrix[, gradients, rf_pulses])Updates the mapping of orientation matrix objects for given Gradient blocks and rf_pulses associated with a slice-selection gradients
remove_block
(block_name)Removes block from internal lookup
rename_blocks
(old_names, new_names)Renames blocks and updates block lookup map
Grids RF-definitions of all blocks contained in the sequence, on a joint time grid from the minimal to maximal value in single time-points definitions with a step-length defined in system_specs.rf_raster_time.
shift_in_time
(shift)Shifts all blocks contained in the sequence object by the specified time
Reverses the sequence in time
validate
()Calls the validation function of each block with self._system_specs
Attributes:
Returns the centers of all adc_blocks in the sequence.
Returns a tuple containing the names of all blocks contained in the sequence object, where temporal ordering is assumed
Time difference of earliest start and latest end of all blocks contained in the sequence
Returns the gradient definitions (t, wf) of all Gradient-type blocks that are contained in the sequence.
Returns the rf definitions (t, amplitude) of RFPulse-type blocks that are contained in the sequence.
Returns the rf events (rf-center, flip-angle) of RFPulse-type blocks that are contained in the sequence.
- adc_to_grid(force_raster=False)[source]#
Grids the ADC-Events of all blocks contained in the sequence as boolean 1D mask along with the resulting time-grid. Additionally, the start and end points of the all adc-blocks are returned. The definition of start/end differ for force_gradient_raster True/False
Boolean mask explanation:
- force_raster == False
events that are not defined on the grid, are inserted into the time-raster resulting in a non-uniform time definition. The boolean values of the newly inserted points are set to 1.
- force_raster == True
for events that are not defined on the grid the boolean values of the interval borders on gradient raster time are set to 1. For events that are already on the grid, the corresponding single index is set 1.
Start/End - definition:
- force_raster == False:
the exact time of first/last event per block is returned.
- force_raster == True:
The returned start/end times correspond to the beginning and end of the plateau of a trapezoidal gradient played out during the adc-events (addition of dwell-time).
- Parameters:
force_raster (
bool
) – bool - defaults to True- Return type:
Tuple
[ndarray
,ndarray
,ndarray
,ndarray
]- Returns:
Tuple(np.array, np.array, np.array) - (t, ) containing time-values - (t, ) containing values of 0 or 1, indicating where the adc is active - (t, ) containing the adc_phase in radians - (#adc_blocks, 2) where (:, 0) contains the indices of the start time of
the adc-block and (:, 1) the end time correspondingly.
- add_block(block, copy=True)[source]#
Add the instance of block to the internal List of sequence blocks.
Note: The internal definition of blocks is mutable, therefore if the new block is not copied, subsequent alterations can have unwanted side-effects inside the sequence.
- Raises:
ValueError – If block.validate() fails to validate using the system specs of self
TypeError – If block is an instance of class SequenceBaseBlock
- Parameters:
block (
SequenceBaseBlock
) – Sequence block to be added to the sequencecopy (
bool
) – Determines if the block is copied before adding it to the sequence
- Return type:
None
- append(other, copy=True, end_time=None)[source]#
If both system specifications match, copies all blocks from other, shifts them by the current end time of this sequence intance (plus an additional delay according to ADC/RF - dead times and RF-ring-down time) and adds the blocks to itself.
- Raises:
ValueError – If other fails to validate using the system specs of self
- Parameters:
other (
Union
[Sequence
,SequenceBaseBlock
]) – Sequence or block to be added to the sequencecopy (
bool
) – if true copies the other sequence objectend_time (
Optional
[Quantity
]) –
- Return type:
None
- calculate_kspace()[source]#
Evaluates the k-space trajectory of the sequence.
Note: All RF-pulses with a smaller flip-angle other than 180° are assumed to be excitation pulses. 180° - Refocusing pulses result in a complex conjugation of the trajectory. Consecutive excitation pulses are handled by starting from k-space center again.
- Return type:
Tuple
[ndarray
,ndarray
,ndarray
]- Returns:
Tuple of arrays containing:
k-space trajectory on gradient rasters (-1, 3) in 1/m
k-space points at adc events (-1, 3) in 1/m
time at adc events (-1 ) in ms
- calculate_moment(moment=0, center_time=<Quantity(0.0, 'millisecond')>, end_time=None, start_time=None)[source]#
Calculates gradient moments about a given center point
- Parameters:
moment (
int
) – int of desired moment numbercenter_time (
Quantity
) – Quantity of center time to calculate moment aboutend_time (
Optional
[Quantity
]) – Time to calculate moment up to, default is end of sequencestart_time (
Optional
[Quantity
]) – Time to calculate moment from, default is start of sequence
- Return type:
Quantity
- Returns:
Quantity [Mx, My, Mz]
- combined_adc()[source]#
Combines all ADC-type blocks contained in the sequence, on a joint time grid.
- Note: The binary event channel of the returned array is technically not needed but adheres to the signature
of dense gridding
- Return type:
Tuple
[ndarray
,ndarray
]- Returns:
Array of shape (t, ) containing the time-points
Array of shape (t, 2) containing binary event and phase
- combined_gradients()[source]#
Combines the gradient definitions of all blocks contained in the sequence, into a joint single definition. The joint time-points are defined by the set of unique time-points of all combined blocks. If gradients occur at the same time on the same channel, they are added.
- Return type:
Tuple
[ndarray
,ndarray
]- Returns:
(np.ndarray, np.ndarray) of shape (t, ) containing the time-points and (3 [gx, gy, gz], t) containing the waveform definition in ms and mT/m returns (None, None) if no gradients are contained in the sequence
- combined_rf()[source]#
Combines the rf-definitions of all blocks contained in the sequence, into a joint single definition. The joint time-points are defined by the set of unique time-points of all combined blocks. If rf occur at the same time they are added.
- Return type:
Tuple
[ndarray
,ndarray
]- Returns:
(np.ndarray, np.ndarray) of shape (t, ) containing the time-points and (t, ) containing the complex RF-waveform definition in ms and uT
- extend(other, copy=True)[source]#
If both system specifications match, copies all blocks from other shifts them by own tmax and adds the blocks to own collection
- Raises:
ValueError – If other fails to validate using the system specs of self
- Parameters:
other (
Sequence
[Union
[Sequence
,SequenceBaseBlock
]]) – ListSequence or block to be added to the sequencecopy (
bool
) – if true copies the other sequence object
- Return type:
None
- get_block(block_name=None, partial_string_match=None, regular_expression=None, typedef=None, invert_pattern=False, sort_by=None)[source]#
Returns reference to the block whose member name matches the specified argument. If no block with given name is present in the sequence, it returns None
Note
Checks which keyword argument to use from left to right as specified in the signature. If multiple are specified uses only the first one.
- Raises:
ValueError if no keyword-argument is specified
- Parameters:
block_name (
Union
[str
,Iterable
[str
],None
]) – String or iterable of strings exactly matching a set of blocks contained in the sequencepartial_string_match (
Union
[str
,Iterable
[str
],None
]) – str or iterable of strings that specify partial string matches. All blocks partially matching at least one are returned.regular_expression (
Union
[str
,Iterable
[str
],None
]) – str or iterable of strings containing regular expressions that are matched against the block-names. All blocks, matching at least one of the given expressions are returned.typedef – type defintion (e.g. cmrseq.bausteine.ADC)
invert_pattern (
bool
) – if True, all blocks except of the pattern-matched names are returnedsort_by (
Optional
[str
]) – from [None, start, end] returns the list of blocks sorted according to their start or end time, is ignored if blocks are retrieved by name
- Return type:
Union
[SequenceBaseBlock
,List
[SequenceBaseBlock
]]- Returns:
SequenceBaseBlock or List of SequenceBaseBlocks depending on the specified argument
- gradients_to_grid(start_time=None)[source]#
Grids gradient definitions of all blocks contained in the sequence, on a joint time grid from the minimal to maximal value in single time-points definitions with a step-length defined in system_specs.grad_raster_time. If gradients occur at the same time on the same channel, they are added.
- Return type:
Tuple
[ndarray
,ndarray
]- Returns:
(np.ndarray, np.ndarray) of shape (t, ) containing the time-grid and (3 [gx, gy, gz], t) containing the waveform definition in ms and mT/m returns (None, None) if no gradients are contained in the sequence
- Parameters:
start_time (Quantity | None) –
- partial_sequence(copy_blocks, partial_string_match=None, regular_expression=None, invert_pattern=False, **kwargs)[source]#
Returns a cmrseq.Sequence object containing references or deep-copies of all blocks matched either with partial-string-match or regular expressions specified as keyword
argument.
- Parameters:
copy_blocks (
bool
) – if True, creates deep-copies of matched blocks.partial_string_match (
Union
[str
,Iterable
[str
],None
]) – str or iterable of strings that specify partial string matches. All blocks partially matching at least one are returned.regular_expression (
Union
[str
,Iterable
[str
],None
]) – str or iterable of strings containing regular expressions that are matched against the block-names. All blocks, matching at least one of the given expressions are returned.invert_pattern (
bool
) – if True, all blocks except of the pattern-matched names are returned
- Return type:
- Returns:
Sequence object
- register_omatrix(matrix, gradients=None, rf_pulses=None)[source]#
Updates the mapping of orientation matrix objects for given Gradient blocks and rf_pulses associated with a slice-selection gradients
- Parameters:
matrix (
OMatrix
) – cmrseq.OMatrix objectgradients (
Optional
[list
[Union
[str
,Gradient
]]]) – List of unique block names or instances of type Gradient to be registered with the given o-matrixrf_pulses (
Optional
[list
[tuple
[Union
[str
,RFPulse
],Union
[str
,TrapezoidalGradient
]]]]) – List of tuples containing block-names or instances of (RF-pulse, TrapezoidalGradients), to be registered with the orientation matrix
- rename_blocks(old_names, new_names)[source]#
Renames blocks and updates block lookup map
- Parameters:
old_names (List[str]) –
new_names (List[str]) –
- rf_to_grid()[source]#
Grids RF-definitions of all blocks contained in the sequence, on a joint time grid from the minimal to maximal value in single time-points definitions with a step-length defined in system_specs.rf_raster_time.
If RF-pulses occur at the same time on the same channel, they are added.
- Return type:
Tuple
[ndarray
,ndarray
]- Returns:
(np.ndarray, np.ndarray) of shape (1, t) containing the time-grid and (1, t) containing the complex RF amplitude
- shift_in_time(shift)[source]#
Shifts all blocks contained in the sequence object by the specified time
- Parameters:
shift (
Quantity
) – Quantity of dimesion time- Return type:
None
- validate()[source]#
Calls the validation function of each block with self._system_specs
- Raises:
ValueError – If any contained block fails to validate with own system specs
ValueError – If any combination of contained acquisition blocks have temporal overlap.
ValueError – If all combined gradient definitions exceed system limits (max amplitude and slew-rate)
- Return type:
None
- property adc_centers: List[Quantity]#
Returns the centers of all adc_blocks in the sequence.
- property blocks: List[str]#
Returns a tuple containing the names of all blocks contained in the sequence object, where temporal ordering is assumed
- property duration: Quantity#
Time difference of earliest start and latest end of all blocks contained in the sequence
- property end_time#
- property gradients: List[Tuple[Quantity, Quantity]]#
Returns the gradient definitions (t, wf) of all Gradient-type blocks that are contained in the sequence. If an OMatrix is registered the gradient channels are rotated accordingly by applying the OMatrix object
- property rf: List[Tuple[Quantity, Quantity]]#
Returns the rf definitions (t, amplitude) of RFPulse-type blocks that are contained in the sequence. If an OMatrix is registered the frequency offset is adjusted accordingly by applying the OMatrix object
- property rf_events: List[Tuple[Quantity, Quantity]]#
Returns the rf events (rf-center, flip-angle) of RFPulse-type blocks that are contained in the sequence.
- property start_time#