from gui.test_interface import TestInterface
from gui.module_test_data import ModuleTestData
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
from tkinter import messagebox
import json
import logging
import os
[docs]
class EyeDiagram(TestInterface):
test_name = "Communication"
def __init__(self, parent, controller, mod_data):
super().__init__(parent, controller, mod_data)
tk.Label(self, text="2.").grid(row=2, column=0)
tk.Button(self, text="View", command=lambda : self.sanitise_plot_eye_diagram(parent, mod_data)).grid(row=2, column=1)
[docs]
def get_test_list(self, mod_data : ModuleTestData):
return ["eyeDiagram"]
[docs]
def gen_cmd(self, mod_data : ModuleTestData):
return "{echo}cd {home_path}/Yarr ; {echo}bin/eyeDiagram -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json" if mod_data.dry_run else "{echo}cd {home_path}/Yarr ; {echo}bin/eyeDiagram -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json > {pwd}/gui/logs/eyeDiagram.log" # if statement removes pipe output for dry runs
[docs]
def sanitise_plot_eye_diagram(self, master, mod_data : ModuleTestData, file : str = r"./gui/logs/eyeDiagram.log"):
"""Reads and sanitises the shell output of the eyeDiagram script. Removes new line breaks, removes pipe delimiter, and removes shell colour information.
Args:
master: controlling tk.Frame to pass through to other functions
mod_data
file (str): path to eyeDiagram.log. Default is ..gui/logs/eyeDiagram.log
"""
logging.debug("Plotting eyeDiagram")
data = []
delay = []
# ANSI escape sequence (\x1b[) + Select Graphic Rendition subset for colours (32 = green, 0 = black). Adds colour to eyeDiagram output
green = r'\x1b[32m'
black = r'\x1b[0m'
with open(file) as f:
lines = f.readline()
logging.debug("Reading line")
while "0 | " not in lines:
lines = f.readline()
for _ in range(32):
line = lines.encode('unicode_escape').decode() # remove weird encoding and convert to bash string
line = line.replace(green, '').replace(black, '')
line = line.replace('\n', '')
print(line)
parts = [x.strip() for x in line.split('|')]
row = [float(val) for val in parts[1:-1]]
data.append(row)
lines = f.readline()
while not "Determining" in lines:
lines = f.readline()
for _ in range(16):
lines = f.readline()
delay.append("green" if "width" in lines else "red")
self.open_eyediagram_popup(master, data, delay, mod_data)
[docs]
def chip_enabled(self, mod_data : ModuleTestData) -> list[int]:
"""Reads the relevant config file, located in module-qc-database-tools, to output which ASICs are turned on.
Args:
mod_data: ModuleTestData object containing ID and serial number
Returns:
enabled: list of integers in [0,1] designating whether the corresponding ASIC is off or on.
"""
loc_id, mod_sn, temp, _ = self.check_mod_data_loaded(mod_data)
enabled = []
home_path = mod_data.home_path
file = os.path.expanduser(f"{home_path}/module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json")
logging.debug(f"Opening {file}")
with open(file, "r") as jsonfile:
data = json.load(jsonfile)
logging.info("Read successful")
for a in range(4):
logging.debug(f"Chip {a} enabled: {data['chips'][a]['enable']} ")
enabled.append((int(data['chips'][a]['enable'])))
return enabled
[docs]
def disable_chips(self, master, mod_data : ModuleTestData, chk_boxes : list):
"""Writes to the config JSON with updated information (from checkboxes) as to which ASICS are to be turned off or on. If there is any write error, the original data is written in stead.
Args:
master: controlling tk.Frame so that the popup can be closed
mod_data: ModuleTestData object containing local ID and serial number, as well as whether it is a warm or cold test so that the correct JSON file can be located.
chk_boxes (list[int]): list of integers corresponding to whether chip[i] is off (0) or on (1).
"""
loc_id, mod_sn, temp, _ = self.check_mod_data_loaded(mod_data)
home_path = mod_data.home_path
file = os.path.expanduser(f"{home_path}/module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json")
with open(file, "r") as jsonfile:
data = json.load(jsonfile)
data_edited = data # to preserve original data in case of RW error
with open(file, "w") as jsonfile:
for a in range(4):
data_edited['chips'][a]['enable'] = chk_boxes[a]
try:
json.dump(data_edited, jsonfile, indent=2)
except:
logging.critical("JSON RW error : unable to save new config")
messagebox.showerror("showerror", "JSON RW error : unable to save new config")
json.dump(data, jsonfile, indent=2)
logging.info("Config edited")
master.destroy()
[docs]
class PrelimTests(TestInterface):
test_name = "Preliminary Tests"
def __init__(self,parent,controller, mod_data):
super().__init__(parent, controller, mod_data)
[docs]
def get_test_list(self, mod_data : ModuleTestData):
if mod_data.stage == "post":
return ['IV-MEASURE']
elif mod_data.stage == "final_cold":
return ['IV-MEASURE', 'ADC-CALIBRATION', 'ANALOG-READBACK', 'SLDO', 'VCAL-CALIBRATION', 'INJECTION-CAPACITANCE', 'DATA-TRANSMISSION']
return ['IV-MEASURE', 'ADC-CALIBRATION', 'ANALOG-READBACK', 'SLDO', 'VCAL-CALIBRATION', 'INJECTION-CAPACITANCE', 'LP-MODE', 'DATA-TRANSMISSION']
[docs]
def gen_cmd(self, mod_data):
return "{echo}cd {home_path}/module-qc-tools ; pwd ; {echo}measurement-{test} -c ../configs/new_hw_config_{version}.json -m ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json"
[docs]
class MinHealthTests(TestInterface):
test_name = "Mininum Health Tests"
[docs]
def get_test_list(self, mod_data):
return ["corecolumnscan", "std_digitalscan", "std_analogscan", "std_thresholdscan_hr", "std_totscan -t 6000"]
[docs]
def gen_cmd(self, mod_data: ModuleTestData):
return "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/rd53b/{test}.json {test_flags} -Wh" if mod_data.version == "v1.1" else "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/itkpixv2/{test}.json {test_flags} -Wh" # changes the config file depending on v1 or v2
[docs]
class Tuning(TestInterface):
test_name = "Tuning"
[docs]
def get_test_list(self, mod_data):
_, _, _, version = self.check_mod_data_loaded(mod_data)
return ["std_tune_globalthreshold -t 1700", "std_tune_globalpreamp -t 6000 7", "std_tune_globalthreshold -t 1700", "std_tune_pixelthreshold -t 1500", "std_thresholdscan_hd", "std_totscan -t 6000"] if version == "v2" else ["std_tune_globalthreshold -t 1700", "std_totscan -t 6000", "std_tune_globalthreshold -t 1700", "std_tune_pixelthreshold -t 1500", "std_retune_globalthreshold -t 1700", "std_retune_pixelthreshold -t 1500", "std_thresholdscan_hd", "std_totscan -t 6000"]
[docs]
def gen_cmd(self, mod_data: ModuleTestData):
return "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/rd53b/{test}.json {test_flags} -Wh" if mod_data.version == "v1.1" else "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/itkpixv2/{test}.json {test_flags} -Wh" # changes the config file depending on v1 or v2
[docs]
class PixelFailTests(TestInterface):
test_name = "Pixel Fail"
[docs]
def get_test_list(self, mod_data):
if mod_data.stage == "final_cold":
return ["std_discbumpscan", "std_mergedbumpscan -t 1500", "std_thresholdscan_zerobias", "std_noisescan", "selftrigger_source -p", "selftrigger_source"]
return ["std_discbumpscan", "std_mergedbumpscan -t 1500", "std_thresholdscan_zerobias", "std_noisescan"]
[docs]
def gen_cmd(self, mod_data: ModuleTestData):
""""Returns the template for the pixel fail test scripts, changing the config depending on the chip version """
return "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/rd53b/{test}.json {test_flags} -Wh" if mod_data.version == "v1.1" else "{echo}cd {home_path}/Yarr ; {echo}bin/scanConsole -r configs/controller/specCfg-rd53b-16x1.json -c ../module-qc-database-tools/{loc_id}/{mod_sn}/{mod_sn}_L2_{temp}.json -s configs/scans/itkpixv2/{test}.json {test_flags} -Wh" # changes the config file depending on v1 or v2