From 8408e9f1f15da7a21119271997f21e34562b625b Mon Sep 17 00:00:00 2001 From: Angela Jia <42385351+22angiej@users.noreply.github.com> Date: Mon, 29 Jul 2024 16:56:18 -0700 Subject: [PATCH] Fix documentation to adhere to Python style --- acquire_automatic.py | 20 ++++---- util.py | 109 +++++++++++++++++++++++++++---------------- 2 files changed, 81 insertions(+), 48 deletions(-) diff --git a/acquire_automatic.py b/acquire_automatic.py index a812945..21cf9b9 100644 --- a/acquire_automatic.py +++ b/acquire_automatic.py @@ -14,14 +14,16 @@ rp_s = scpi.scpi(IP) print('Connected to ' + IP) -''' -Runs one shot of driving the speaker with a waveform and collecting the relevant data. - -@param store_data: whether to save time, measured speaker & PD voltage, - and expected speaker velocity data to h5py -@param plot_data: whether to plot data after acquisition -''' def run_one_shot(start_freq=1, end_freq=1000, decimation=8192, store_data=False, plot_data=False): + """Runs one shot of driving the speaker with a waveform and collecting the relevant data. + + Args: + start_freq (int, optional): the lower bound of the valid frequency range. Defaults to 1. + end_freq (int, optional): the upper bound of the valid frequency range. Defaults to 1000. + decimation (int, optional): Decimation that determines sample rate, should be power of 2. Defaults to 8192. + store_data (bool, optional): Whether to store data in h5py file. Defaults to False. + plot_data (bool, optional): Whether to plot data after acquisition. Defaults to False. + """ ##### Create Waveform ##### N = 16384 # Number of samples in buffer @@ -129,6 +131,6 @@ def run_one_shot(start_freq=1, end_freq=1000, decimation=8192, store_data=False, rp_s.tx_txt('ACQ:RST') -num_shots = 1e3 +num_shots = 1 for i in range(num_shots): - run_one_shot(store_data=False, plot_data=False) \ No newline at end of file + run_one_shot(store_data=False, plot_data=True) \ No newline at end of file diff --git a/util.py b/util.py index 2d26968..4e82f3e 100644 --- a/util.py +++ b/util.py @@ -2,10 +2,18 @@ from scipy.fftpack import fft, ifft, fftfreq import h5py -''' -Generates a random waveform within the given frequency range of a given length. -''' -def bounded_frequency_waveform(start_frequency, end_frequency, length=1000, sample_rate=1000): +def bounded_frequency_waveform(start_frequency, end_frequency, length, sample_rate): + """Generates a random waveform within the given frequency range of a given length. + + Args: + start_frequency (float): the lower bound of the valid frequency range + end_frequency (float): the upper bound of the valid frequency range + length (int): the number of values to generate + sample_rate (float): the rate at which to sample values + + Returns: + [1darr, 1darr]: the array of time points and amplitude points in time domain + """ # Create an evenly spaced time array t = np.linspace(0, 1.0, length, False) # 1 second # Generate a random frequency spectrum between the start and end frequencies @@ -23,12 +31,17 @@ def bounded_frequency_waveform(start_frequency, end_frequency, length=1000, samp y = np.fft.fftshift(y) return t, y -''' -Linearly scales data to a new range. - -@param data: assumed to be 1D array -''' def linear_convert(data, new_min=-1, new_max=1): + """Linearly scales data to a new range. Default is [-1, 1]. + + Args: + data (1darr): data to scale + new_min (float, optional): new minimum value for data. Defaults to -1. + new_max (float, optional): new maximum value for data. Defaults to 1. + + Returns: + 1darr: the newly scaled data + """ old_min = np.min(data) old_max = np.max(data) old_range = old_max - old_min @@ -36,13 +49,12 @@ def linear_convert(data, new_min=-1, new_max=1): return new_min + new_range * (data - old_min) / old_range def write_data(file_path, entries): - '''Add data to a given dataset in 'file'. Creates dataset if it doesn't exist; otherwise, - appends. - - Keyword arguments: - file_path (string) - the name of the output HDF5 file to which to append data - entries (dict) - dictionary of column name & corresponding data - ''' + """Add data to a given dataset in 'file'. Creates dataset if it doesn't exist; + otherwise, appends. + Args: + file_path (string): the name of the output HDF5 file to which to append data + entries (dict): dictionary of column name & corresponding data + """ with h5py.File(file_path, 'a') as f: for col_name, col_data in entries.items(): if col_name in f.keys(): @@ -61,31 +73,43 @@ def write_data(file_path, entries): k = 33.42493417407945 c = -3.208233068626455 -''' -Calculates the expected displacement of the speaker at an inputted drive amplitude 'ampl' -for a given frequency 'f', based on the calibration fit at 0.2Vpp. - -@param f: frequencies at which to calculate expected displacement -@return: expected displacement in microns -''' def A(f): - return (k * f0**2) / np.sqrt((f0**2 - f**2)**2 + f0**2*f**2/Q**2) + """Calculates the expected displacement of the speaker at an inputted drive amplitude 'ampl' for a given frequency 'f', + based on the calibration fit at 0.2Vpp. + + Args: + f (1darr): frequencies at which to calculate expected displacement -''' -Calculates the phase delay between the speaker voltage waveform and the photodiode response -at a given frequency 'f'. + Returns: + 1darr: expected displacement/V_ampl in microns/V + """ + return (k * f0**2) / np.sqrt((f0**2 - f**2)**2 + f0**2*f**2/Q**2) -@param f: optimal range 20Hz-1kHz -@return: phase in radians -''' def phase(f): + """Calculates the phase delay between the speaker voltage waveform and the photodiode response + at a given frequency 'f'. + + Args: + f (1darr): frequencies at which to calculate expected displacement + + Returns: + 1darr: phase in radians + """ return np.arctan2(f0/Q*f, f**2 - f0**2) + c -''' -Calculates the corresponding displacement waveform based on the given voltage waveform -using calibration. -''' def displacement_waveform(speaker_data, sample_rate): + """Calculates the corresponding displacement waveform based on the given voltage waveform + using calibration. + + Args: + speaker_data (1darr): voltage waveform for speaker + sample_rate (float): sample rate used to generate voltage waveform + + Returns: + [1darr, 1darr, 1darr]: converted displacement waveform (microns) in time domain, + converted displacement waveform in frequency domain, + frequency array (Hz) + """ speaker_spectrum = fft(speaker_data) n = speaker_data.size sample_spacing = 1/sample_rate @@ -97,11 +121,19 @@ def displacement_waveform(speaker_data, sample_rate): return y, converted_signal, freq -''' -Calculates the corresponding velocity waveform based on the given voltage waveform -using calibration. -''' def velocity_waveform(speaker_data, sample_rate): + """Calculates the corresponding velocity waveform based on the given voltage waveform + using calibration. + + Args: + speaker_data (1darr): voltage waveform for speaker + sample_rate (float): sample rate used to generate voltage waveform + + Returns: + [1darr, 1darr, 1darr]: converted velocity waveform (microns/s) in time domain, + converted velocity waveform in frequency domain, + frequency array (Hz) + """ speaker_spectrum = fft(speaker_data) n = speaker_data.size sample_spacing = 1/sample_rate @@ -110,6 +142,5 @@ def velocity_waveform(speaker_data, sample_rate): # Multiply signal by transfer func in freq domain, then return to time domain converted_signal = 1j*freq * speaker_spectrum * A(freq) * np.where(freq < 0, np.exp(-1j*phase(-freq)), np.exp(1j*phase(freq))) v = np.real(ifft(converted_signal)) -# y = np.fft.fftshift(y) return v, converted_signal, freq \ No newline at end of file