diff --git a/Python/waveform.py b/Python/waveform.py index 6d962943bf6620f3b9337b367241a85a232465b7..9e29f4cd9e822598f6061eba369a40ccdb695ae6 100644 --- a/Python/waveform.py +++ b/Python/waveform.py @@ -3,7 +3,7 @@ from typing import Dict, Tuple, Any, List import numpy as np from scipy.interpolate import interp1d from AWG import * -import cupy as cp +# import cupy as cp class Waveform: @@ -214,7 +214,8 @@ def create_path_table_gpu( path_table = {} # lookup table to store all moves static_sig = cp.zeros(sample_len) # for fast real-time waveform generation purposes t = cp.arange(sample_len) / wfm.sample_rate # time series - + dt = t[1] + t += dt nt = len(wfm.omega) diagonal_mat = cp.sin( @@ -239,7 +240,7 @@ def create_path_table_gpu( # I advise reading through the notes page first before going further dw = omega_j - omega_i # delta omega in the equation adw = abs(dw) - t_tot = np.sqrt(abs(4 * dw / a_max)) # calculate minimum time to complete move + t_tot = np.sqrt(abs(4 * dw / a_max)) + dt # calculate minimum time to complete move phi_j = wfm.phi[j] % twopi # wrap around two pi phi_i = wfm.phi[i] % twopi @@ -396,57 +397,63 @@ def create_moving_array_GPUOTF( return -def create_moving_signal_single(omega_i, omega_f, sample_rate, signal_time): - min_len = 2 * sample_rate / (10e3) +def create_moving_signal_single( + omega_i, omega_f, sample_rate, signal_time, amp=2**12, phi=0 +): + min_len = 2 * sample_rate / (1e3) sample_len = sample_rate * signal_time sample_len += min_len - sample_len % min_len sample_len = int(sample_len) t = np.arange(sample_len) / sample_rate - t_tot = sample_len / sample_rate + t += t[1] + t_tot = sample_len / sample_rate + t[1] a = 4 * (omega_i - omega_f) / (t_tot ** 2) end = sample_len half = int(end / 2) + 1 t1 = t[:half] t2 = t[half:end] - t_tot / 2 - amps = 2**12 signal = np.zeros(sample_len) - signal[:half] = omega_i * t1 - a / 6 * t1 ** 3 # t<=T/2 + signal[:half] = phi + omega_i * t1 - a / 6 * t1 ** 3 # t<=T/2 # ph = wfm.phi[i] + omega_i * t_tot / 2 + a / 6 * (t_tot / 2) ** 3 signal[half:end] = signal[half - 1] + \ (omega_i - a / 2 * (t_tot / 2) ** 2) * t2 - \ a / 2 * t_tot / 2 * t2 ** 2 + \ a / 6 * t2 ** 3 # t>=T/2 signal[end:] = signal[end - 1] + omega_f * (t[end:] - t[end - 1]) - signal = (amps * np.sin(signal)).astype(np.int16) - return signal + phi_end = signal[-1] + signal = amp * np.sin(signal) + return signal.astype(np.int16), phi_end -def create_move_then_back(omega_i, omega_f, sample_rate, move_time, stay_time): - min_len = 2 * sample_rate / 0.1e3 - sample_len = sample_rate * (move_time * 2 + stay_time) +def create_static_signal_single( + omega, sample_rate, signal_time, amp=2 ** 12, phi=0 +): + min_len = 2 * sample_rate / (1e3) + sample_len = sample_rate * signal_time sample_len += min_len - sample_len % min_len sample_len = int(sample_len) t = np.arange(sample_len) / sample_rate - t_tot = sample_len / sample_rate - a = 4 * (omega_i - omega_f) / (t_tot ** 2) - end = sample_len - half = int(end / 2) + 1 - t1 = t[:half] - t2 = t[half:end] - t_tot / 2 + t += t[1] + signal = phi + omega * t + phi_end = signal[-1] + signal = amp * np.sin(signal) + return signal.astype(np.int16), phi_end - amps = 2**12 - signal = np.zeros(sample_len) - signal[:half] = omega_i * t1 - a / 6 * t1 ** 3 # t<=T/2 - # ph = wfm.phi[i] + omega_i * t_tot / 2 + a / 6 * (t_tot / 2) ** 3 - signal[half:end] = signal[half - 1] + \ - (omega_i - a / 2 * (t_tot / 2) ** 2) * t2 - \ - a / 2 * t_tot / 2 * t2 ** 2 + \ - a / 6 * t2 ** 3 # t>=T/2 - signal[end:] = signal[end - 1] + omega_f * (t[end:] - t[end - 1]) - signal = (amps * np.sin(signal)).astype(np.int16) +def create_move_then_back(omega_i, omega_f, sample_rate, move_time, stay_time): + move0, phi0 = create_moving_signal_single( + omega_i, omega_f, sample_rate, move_time + ) + stay, phi1 = create_static_signal_single( + omega_f, sample_rate, stay_time, phi=phi0 + ) + move1, phi2 = create_moving_signal_single( + omega_f, omega_i, sample_rate, move_time, phi=phi1 + ) + signal = np.concatenate((move0, stay, move1)) return signal +