From 8ae2dd7a9fe0be0ec8fa901d98c6cd4cf08c5dbf Mon Sep 17 00:00:00 2001 From: xiyehu2 <35537592+xiyehu2@users.noreply.github.com> Date: Tue, 6 Dec 2022 17:09:39 -0600 Subject: [PATCH] single moving signal generation --- Python/waveform.py | 50 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/Python/waveform.py b/Python/waveform.py index fd9ffdf..51741c8 100644 --- a/Python/waveform.py +++ b/Python/waveform.py @@ -1,4 +1,6 @@ from typing import Dict, Tuple, Any + +import numpy as np from scipy.interpolate import interp1d from AWG import * @@ -136,10 +138,11 @@ def create_path_table(wfm: Waveform) -> any: def create_path_table_reduced( - wfm: Waveform, target_idx, max_dist=np.inf + wfm: Waveform, target_idx, max_dist=np.inf, save_path=None ) -> Tuple[Dict[Tuple[int, int], np.ndarray], np.ndarray]: """ create a dim-3 look up table where the table[i,j] contains a sine wave to move tweezer i to tweezer j + :param save_path: file saving path :param target_idx: indices of target pattern :param max_dist: maximum move distance in indices :param wfm: waveform object already initialized with basic parameters. @@ -179,7 +182,8 @@ def create_path_table_reduced( path_table = {} # lookup table to store all moves static_sig = np.zeros(sample_len) # for fast real-time waveform generation purposes t = np.arange(sample_len) / wfm.sample_rate # time series - # iterate! I think this part can be vectorized as well... but unnecessary. + + # iterate! for i in range(n): omega_i = wfm.omega[i] for j in moves[i]: # j is the target position, i is starting position @@ -259,6 +263,10 @@ def create_path_table_reduced( path_table[key] -= path_table[(key[1], key[1])] # for fast real-time generation # path_table[key] = path_table[key].astype(np.int16) + # save stuff if prompted + if save_path is not None: + np.savez(save_path, table=path_table, static_sig=static_sig, wfm=wfm, target=target_idx) + return path_table, static_sig.astype(np.int16) @@ -313,18 +321,23 @@ def create_moving_array(path_table: np.ndarray, paths: np.ndarray) -> np.ndarray def create_moving_array_reduced( - sig: np.ndarray, path_table: Dict, - paths: np.ndarray, - off: np.ndarray + sig: np.ndarray, + filled_idx: np.ndarray, + target_idx: np.ndarray, + # paths: np.ndarray, + # off: np.ndarray ): """ create a rearranging signal that moves tweezers as specified by paths. :param sig: initially a static-array-generating waveform. :param path_table: lookup table returned from create_path_table_reduced(). + :param filled_idx: see get_rearrange_paths for detail. + :param target_idx: see get_rearrange_paths for detail. :param paths: 2d array with moving trajectories, [:,0] stores start pos, [:,1] stores end pos. :param off: 1d array with tweezer indices that need to be set to 0. """ + paths, off = get_rearrange_paths(filled_idx, target_idx) for i, j in paths: if i == j: continue @@ -335,3 +348,30 @@ def create_moving_array_reduced( for i in off: sig -= path_table[(i, i)] pass + + +def create_moving_signal_single(omega_i, omega_f, sample_rate, signal_time): + min_len = 2 * sample_rate / (10e3) + 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 * np.abs(omega_f - omega_i) / (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 + # 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]) + path = (amps * np.sin(signal)).astype(np.int16) -- GitLab