| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- from types import SimpleNamespace
- import numpy as np
- from seqgen.pypulseq.opts import Opts
- def make_arbitrary_grad(
- channel: str,
- waveform: np.ndarray,
- delay: float = 0,
- max_grad: float = 0,
- max_slew: float = 0,
- system: Opts = Opts(),
- ) -> SimpleNamespace:
- """
- Creates a gradient event with arbitrary waveform.
- See also `pypulseq.Sequence.sequence.Sequence.add_block()`.
- Parameters
- ----------
- channel : str
- Orientation of gradient event of arbitrary shape. Must be one of `x`, `y` or `z`.
- waveform : numpy.ndarray
- Arbitrary waveform.
- system : Opts, default=Opts()
- System limits.
- max_grad : float, default=0
- Maximum gradient strength.
- max_slew : float, default=0
- Maximum slew rate.
- delay : float, default=0
- Delay in seconds (s).
- Returns
- -------
- grad : SimpleNamespace
- Gradient event with arbitrary waveform.
- Raises
- ------
- ValueError
- If invalid `channel` is passed. Must be one of x, y or z.
- If slew rate is violated.
- If gradient amplitude is violated.
- """
- if channel not in ["x", "y", "z"]:
- raise ValueError(
- f"Invalid channel. Must be one of x, y or z. Passed: {channel}"
- )
- if max_grad <= 0:
- max_grad = system.max_grad
- if max_slew <= 0:
- max_slew = system.max_slew
- g = waveform
- slew = np.squeeze(np.subtract(g[1:], g[:-1]) / system.grad_raster_time)
- if max(abs(slew)) >= max_slew:
- raise ValueError(f"Slew rate violation {max(abs(slew)) / max_slew * 100}")
- if max(abs(g)) >= max_grad:
- raise ValueError(f"Gradient amplitude violation {max(abs(g)) / max_grad * 100}")
- grad = SimpleNamespace()
- grad.type = "grad"
- grad.channel = channel
- grad.waveform = g
- grad.delay = delay
- # True timing and aux shape data
- grad.tt = (np.arange(1, len(g) + 1) - 0.5) * system.grad_raster_time
- grad.shape_dur = len(g) * system.grad_raster_time
- grad.first = (3 * g[0] - g[1]) * 0.5 # Extrapolate by 1/2 gradient raster
- grad.last = (g[-1] * 3 - g[-2]) * 0.5 # Extrapolate by 1/2 gradient raster
- return grad
|