def split_gradient_at(grad: np.ndarray, time_point: float, system: Opts = Opts()): """ Split gradient waveform `grad` into two at time point `time_point`. Parameters ---------- grad : numpy.ndarray Gradient waveform to be split into two gradient waveforms. time_point : float, optional Time point at which `grad` will be split into two gradient waveforms. system : Opts, optional System limits. Default is a system limits object initialised to default values. Returns ------- grad1, grad2 : numpy.ndarray Gradient waveforms after splitting. """ grad_raster_time = system.grad_raster_time time_index = round(time_point / grad_raster_time) time_point = time_index * grad_raster_time time_index += 1 if grad.type == 'trap': ch = grad.channel grad.delay = round(grad.delay / grad_raster_time) * grad_raster_time grad.rise_time = round(grad.rise_time / grad_raster_time) * grad_raster_time grad.flat_time = round(grad.flat_time / grad_raster_time) * grad_raster_time grad.fall_time = round(grad.fall_time / grad_raster_time) * grad_raster_time if grad.flat_time == 0: times = [0, grad.rise_time, grad.rise_time + grad.fall_time] amplitudes = [0, grad.amplitude, 0] else: times = [0, grad.rise_time, grad.rise_time + grad.flat_time, grad.rise_time + grad.flat_time + grad.fall_time] amplitudes = [0, grad.amplitude, grad.amplitude, 0] if time_point < grad.delay: times = np.insert(grad.delay + times, 0, 0) amplitudes = [0, amplitudes] grad.delay = 0 amplitudes = np.array(amplitudes) times = np.array(times) amp_tp = np.interp(x=time_point, xp=times, fp=amplitudes) times1 = np.append(times[np.where(times < time_point)], time_point) amplitudes1 = np.append(amplitudes[np.where(times < time_point)], amp_tp) times2 = np.insert(times[times > time_point], 0, time_point) - time_point amplitudes2 = np.insert(amplitudes[times > time_point], 0, amp_tp) grad1 = make_extended_trapezoid(channel=ch, system=system, times=times1, amplitudes=amplitudes1, skip_check=True) grad1.delay = grad.delay grad2 = make_extended_trapezoid(channel=ch, system=system, times=times2, amplitudes=amplitudes2, skip_check=True) grad2.delay = time_point return grad1, grad2 elif grad.type == 'grad': if time_index == 1 or time_index >= len(grad.t): return grad else: grad1 = grad grad2 = grad grad1.last = grad.waveform[time_index] grad2.first = grad.waveform[time_index] grad2.delay = grad.delay + grad.t[time_index] grad1.t = grad.t[:time_index] grad1.waveform = grad.waveform[:time_index] grad2.t = grad.t[time_index:] grad2.waveform = grad.waveform[time_index:] return grad1, grad2 else: raise ValueError('Splitting of unsupported event.')
def split_gradient(grad: np.ndarray, system: Opts = Opts()): """ Split gradient waveform `grad` into two gradient waveforms at the center. Parameters ---------- grad : numpy.ndarray Gradient waveform to be split into two gradient waveforms. system : Opts, optional System limits. Default is a system limits object initialised to default values. Returns ------- grad1, grad2 : numpy.ndarray Split gradient waveforms. """ grad_raster_time = system.grad_raster_time total_length = calc_duration(grad) if grad.type == 'trap': ch = grad.channel grad.delay = round(grad.delay / grad_raster_time) * grad_raster_time grad.rise_time = round( grad.rise_time / grad_raster_time) * grad_raster_time grad.flat_time = round( grad.flat_time / grad_raster_time) * grad_raster_time grad.fall_time = round( grad.fall_time / grad_raster_time) * grad_raster_time times = [0, grad.rise_time] amplitudes = [0, grad.amplitude] ramp_up = make_extended_trapezoid(channel=ch, system=system, times=times, amplitudes=amplitudes, skip_check=True) ramp_up.delay = grad.delay times = [0, grad.fall_time] amplitudes = [grad.amplitude, 0] ramp_down = make_extended_trapezoid(channel=ch, system=system, times=times, amplitudes=amplitudes, skip_check=True) ramp_down.delay = total_length - grad.fall_time ramp_down.t = ramp_down.t * grad_raster_time flat_top = SimpleNamespace() flat_top.type = 'grad' flat_top.channel = ch flat_top.delay = grad.delay + grad.rise_time flat_top.t = np.arange(step=grad_raster_time, stop=ramp_down.delay - grad_raster_time - grad.delay - grad.rise_time) flat_top.waveform = grad.amplitude * np.ones(len(flat_top.t)) flat_top.first = grad.amplitude flat_top.last = grad.amplitude return ramp_up, flat_top, ramp_down elif grad.type == 'grad': raise ValueError( 'Splitting of arbitrary gradients is not implemented yet.') else: raise ValueError('Splitting of unsupported event.')