Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests/analog: validate M2kAnalogOut features introduced in fw0.33 #369

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
604 changes: 435 additions & 169 deletions tests/analog_functions.py

Large diffs are not rendered by default.

44 changes: 4 additions & 40 deletions tests/bug_checks_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,16 @@
import matplotlib.pyplot as plt
import libm2k

from helpers import get_result_files, plot_to_file
from open_context import ctx_timeout, ctx, ain, aout, trig

gen_reports = True


def test_dac_artifact(ain, aout, trig, chn):
# check for DAC artifacts at slow sample rates
if gen_reports:
from create_files import results_file, results_dir, csv, open_files_and_dirs
if results_file is None:
file, dir_name, csv_path = open_files_and_dirs()
else:
file = results_file
dir_name = results_dir
csv_path = csv
else:
file = []
file_name, dir_name, csv_path = get_result_files(gen_reports)

buffer_size = 4000
sampling_frequency_in = 1000000
sampling_frequency_out = 750000
Expand Down Expand Up @@ -63,33 +56,4 @@ def generate_clock_signal():
buffer.append(1)
for i in range(256):
buffer.append(0)
return buffer


def plot_to_file(title, data, dir_name, filename, xlabel=None, ylabel=None, data1=None):
# Saves the plots in a separate folder
# Arguments:
# title -- Title of the plot
# data -- Data to be plotted
# filename -- Name of the file with the plot
# Keyword Arguments:
# xlabel -- Label of x-Axis (default: {None})
# ylabel -- Label of y-Axis(default: {None})
# data1 -- Data that should be plotted on the same plot(default: {None})
# plot the signals in a separate folder
plt.title(title)
if xlabel is not None: # if xlabel and ylabel are not specified there will be default values
plt.xlabel(xlabel)
else:
plt.xlabel('Samples')
if ylabel is not None:
plt.ylabel(ylabel)
else:
plt.ylabel('Voltage [V]')
plt.grid(visible=True)
plt.plot(data) # if a second set of data must be printed (for ch0 and ch1 phase difference in this case)
if data1 is not None:
plt.plot(data1)
plt.savefig(dir_name + "/" + filename)
plt.close()
return
return buffer
81 changes: 8 additions & 73 deletions tests/digital_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,18 @@
import libm2k
from multiprocessing.pool import ThreadPool
import threading
from pandas import DataFrame
import random
import time
from open_context import ctx
from helpers import get_result_files, save_data_to_csv, plot_to_file
import reset_def_values as reset

from scipy.signal import find_peaks

sample = random.randint(0, 255)
gen_reports = True


def result_files(gen_reports):
if gen_reports:
from create_files import results_file, results_dir, csv, open_files_and_dirs
if results_file is None:
file, dir_name, csv_path = open_files_and_dirs()
else:
file = results_file
dir_name = results_dir
csv_path = csv
else:
file = []
dir_name = []
csv_path = []

return file, dir_name, csv_path


def dig_reset(dig):
# Reset digital object
# Arguments:
# dig -- Digital object

dig.setSampleRateIn(10000)
dig.setSampleRateOut(10000)
dig.setCyclic(True)
dig.setDirection(0b1111111111111111)
for i in range(16):
dig.setOutputMode(i, 1)
dig.enableAllOut(True)
return


def set_digital_trigger(dig):
# Set the digital trigger
# Arguments:
Expand All @@ -59,7 +29,6 @@ def set_digital_trigger(dig):


def check_digital_channels_state(dig, channel):

dig.reset()
# enable channel under test
dig.setDirection(channel, libm2k.DIO_OUTPUT)
Expand Down Expand Up @@ -142,8 +111,9 @@ def get_data_to_check_trig_condition(dig, channel, i, buff):


def check_digital_trigger(channel, dig, d_trig):
file_name, dir_name, csv_path = result_files(gen_reports)
dig_reset(dig)
file_name, dir_name, csv_path = get_result_files(gen_reports)

reset.digital(dig)
delay = 1

condition = [libm2k.RISING_EDGE_DIGITAL, libm2k.FALLING_EDGE_DIGITAL, libm2k.LOW_LEVEL_DIGITAL,
Expand Down Expand Up @@ -249,7 +219,8 @@ def task1(nb_samples, dig):


def test_digital_cyclic_buffer(dig, d_trig, channel):
file, dir_name, csv_path = result_files(gen_reports)
file, dir_name, csv_path = get_result_files(gen_reports)

dig.setDirection(channel, libm2k.DIO_OUTPUT)
dig.enableChannel(channel, True)
d_trig.setDigitalCondition(channel, libm2k.LOW_LEVEL_DIGITAL)
Expand Down Expand Up @@ -285,36 +256,6 @@ def test_digital_cyclic_buffer(dig, d_trig, channel):
passed = False
return passed


def plot_to_file(title, data, dir_name, filename, xlabel=None, ylabel=None, data1=None):
# Saves the plots in a separate folder
# Arguments:
# title -- Title of the plot\n
# data -- Data to be plotted\n
# filename -- Name of the file with the plot\n
# Keyword Arguments:
# xlabel -- Label of x-Axis (default: {None})
# ylabel -- Label of y-Axis(default: {None})
# data1 -- Data that should be plotted on the same plot(default: {None})

# plot the signals in a separate folder
plt.title(title)
if xlabel is not None: # if xlabel and ylabel are not specified there will be default values
plt.xlabel(xlabel)
else:
plt.xlabel('Samples')
if ylabel is not None:
plt.ylabel(ylabel)
else:
plt.ylabel('Voltage [V]')
plt.grid(visible=True)
plt.plot(data) # if a second set of data must be printed (for ch0 and ch1 phase difference in this case)
if data1 is not None:
plt.plot(data1)
plt.savefig(dir_name + "/" + filename)
plt.close()
return

def plot_to_file_all_channels(title, data, dir_name, filename, xlabel=None, ylabel=None):
# Saves the plots in a separate folder
# Arguments:
Expand Down Expand Up @@ -344,11 +285,6 @@ def plot_to_file_all_channels(title, data, dir_name, filename, xlabel=None, ylab
plt.close()
return

def save_data_to_csv(csv_vals, csv_file):
df = DataFrame(csv_vals)
df.to_csv(csv_file)
return

def test_kernel_buffers(dig, nb_kernel_buffers):
error = False
dig.reset()
Expand Down Expand Up @@ -405,7 +341,6 @@ def test_pattern_generator_pulse(dig, d_trig, channel):
test_name = "pattern_generator_glitch"
data_string = []

file_name, dir_name, csv_path = result_files(gen_reports)
dig.reset()
ctx.setTimeout(timeout)

Expand Down
135 changes: 135 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@

import numpy as np
from pandas import DataFrame
import matplotlib.pyplot as plt



def get_result_files(gen_reports):
if gen_reports:
from create_files import results_file, results_dir, csv, open_files_and_dirs
if results_file is None:
file, dir_name, csv_path = open_files_and_dirs()
else:
file = results_file
dir_name = results_dir
csv_path = csv
else:
file = []
dir_name = []
csv_path = []

return file, dir_name, csv_path


def save_data_to_csv(csv_vals, csv_file):
df = DataFrame(csv_vals)
df.to_csv(csv_file)
return


def plot_to_file(title, data, dir_name, filename, xlabel=None, x_lim = None, ylabel=None, y_lim = None, data1=None, x_data = None, data_marked=None):
# Saves the plots in a separate folder
# Arguments:
# title -- Title of the plot
# data -- Data to be plotted
# filename -- Name of the file with the plot
# Keyword Arguments:
# xlabel -- Label of x-Axis (default: {None})
# ylabel -- Label of y-Axis(default: {None})
# data1 -- Data that should be plotted on the same plot(default: {None})
# data_marked -- Data that represents specific points on the plot(default: {None})
# plot the signals in a separate folder
plt.title(title)
# if xlabel and ylabel are not specified there will be default values
if xlabel is not None:
plt.xlabel(xlabel)
else:
plt.xlabel('Samples')
if ylabel is not None:
plt.ylabel(ylabel)
else:
plt.ylabel('Voltage [V]')
plt.grid(visible=True)
# if x_data is not None, the plot will be displayed with the specified x_data
if x_data is not None:
plt.plot(x_data, data)
else:
plt.plot(data)
# if a second set of data must be printed (for ch0 and ch1 phase difference in this case)
if data1 is not None:
if x_data is not None:
plt.plot(x_data, data1)
else:
plt.plot(data1)
# Optional configurations
if x_lim is not None:
plt.xlim(*x_lim)
if y_lim is not None:
plt.ylim(*y_lim)
if data_marked is not None:
plt.plot(data_marked, data[data_marked], 'xr')
plt.savefig(dir_name + "/" + filename)
plt.close()
return

def plot_to_file_multiline(
title,
datasets,
dir_name,
filename,
xlabel="Samples", ylabel="Voltage [V]",
xlim = None, ylim = None,
):
plt.title(title)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.grid(visible=True)

for data in datasets:
xdata, ydata, fmt = data
if xdata is not None:
if "marker" in fmt:
# Mark scattered points
plt.plot(xdata, ydata[xdata], linestyle="None", **fmt)
else:
plt.plot(xdata, ydata, **fmt)
else:
plt.plot(ydata, **fmt)

if xlim is not None:
plt.xlim(*xlim)
if ylim is not None:
plt.ylim(*ylim)
plt.legend()

plt.savefig(f"{dir_name}/{filename}")
plt.close()
return


def get_time_format(samples, sample_rate):
x_time = np.linspace(0, samples/sample_rate, samples)

if x_time[-1] < 1e-6:
x_time *= 1e9
x_label = "Time [ns]"
elif x_time[-1] < 1e-3:
x_time *= 1e6
x_label = "Time [us]"
elif x_time[-1] < 1:
x_time *= 1e3
x_label = "Time [ms]"
else:
x_label = "Time [s]"
return x_time, x_label


def get_sample_rate_display_format(sample_rate):
if sample_rate < 1e3:
return f"{sample_rate:.2f} Hz"
if sample_rate < 1e6:
return f"{sample_rate/1e3:.2f} KHz"
if sample_rate < 1e9:
return f"{sample_rate/1e6:.2f} MHz"
return f"{sample_rate/1e9:.2f} GHz"
Loading
Loading