From b43c9ee57e6347674ce66d68f4999286809b8e58 Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Mon, 6 Nov 2023 15:29:55 -0500 Subject: [PATCH 1/4] adding MODULEID as forced argument, consistency between threshold scan options --- test_ETROC.py | 74 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/test_ETROC.py b/test_ETROC.py index b1f5ded..d6ecd07 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -155,11 +155,25 @@ if __name__ == '__main__': argParser.add_argument('--row', action='store', default=4, help="Pixel row to be tested") argParser.add_argument('--col', action='store', default=3, help="Pixel column to be tested") argParser.add_argument('--pixel_mask', action='store', default=None, help="Pixel mask to apply") + argParser.add_argument('--moduleid', action='store', default=0, help="") args = argParser.parse_args() + assert int(args.moduleid)>0, "Module ID is not specified. This is a new feature, please run with --moduleid MODULEID, where MODULEID is the number on the module test board." + MID = args.moduleid - if not os.path.isdir("results/"): - os.makedirs("results/") + timestamp = time.time() + + result_dir = f"results/{MID}/{timestamp}/" + out_dir = f"outputs/{MID}/{timestamp}/" + + if not os.path.isdir(result_dir): + os.makedirs(result_dir) + + if not os.path.isdir(out_dir): + os.makedirs(out_dir) + + print(f"Will test module with ID {MID}.") + print(f"All results will be stored under timestamp {timestamp}") if args.test_readwrite: # ============================== @@ -447,6 +461,7 @@ if __name__ == '__main__': print("\n - Getting internal test data") + etroc.wr_reg("DAC", 0, broadcast=True) # make sure that we're not additionally picking up any noise etroc.wr_reg("selfTestOccupancy", 2, broadcast=True) if not args.partial: etroc.wr_reg("workMode", 0x1, broadcast=True) @@ -515,7 +530,6 @@ if __name__ == '__main__': print(f"Events with at least one hit {n_events_hit=}") print(f"Events with some error in data unpacking {n_events_err=}") - plot_dir = './output/' fig, ax = plt.subplots(1,1,figsize=(7,7)) hit_matrix.plot2d( ax=ax, @@ -532,8 +546,8 @@ if __name__ == '__main__': fontsize=15, ) name = 'hit_matrix_internal_test_pattern' - fig.savefig(os.path.join(plot_dir, "{}.pdf".format(name))) - fig.savefig(os.path.join(plot_dir, "{}.png".format(name))) + fig.savefig(os.path.join(result_dir, f"{name}.pdf")) + fig.savefig(os.path.join(tesult_dir, f"{name}.png")) fifo.reset() print("\n - Testing fast command communication - Sending two L1As") @@ -610,8 +624,8 @@ if __name__ == '__main__': fontsize=15, ) name = 'hit_matrix_external_L1A' - fig.savefig(os.path.join(plot_dir, "{}.pdf".format(name))) - fig.savefig(os.path.join(plot_dir, "{}.png".format(name))) + fig.savefig(os.path.join(result_dir, "{}.pdf".format(name))) + fig.savefig(os.path.join(result_dir, "{}.png".format(name))) print("\nOccupancy vs column:") @@ -619,6 +633,7 @@ if __name__ == '__main__': print("\nOccupancy vs row:") hit_matrix[{"col":sum}].show(columns=100) + # Set the chip back into well-defined workMode 0 etroc.wr_reg("workMode", 0x0, broadcast=True) if args.threshold == 'auto': @@ -661,8 +676,8 @@ if __name__ == '__main__': ax.set_xlabel(r'$Column$') fig.colorbar(cax,ax=ax) name = 'baseline_auto_individual' - fig.savefig(os.path.join(plot_dir, "{}.pdf".format(name))) - fig.savefig(os.path.join(plot_dir, "{}.png".format(name))) + fig.savefig(os.path.join(result_dir, "{}.pdf".format(name))) + fig.savefig(os.path.join(result_dir, "{}.png".format(name))) fig, ax = plt.subplots(1,1,figsize=(7,7)) cax = ax.matshow(noise_width) @@ -670,10 +685,13 @@ if __name__ == '__main__': ax.set_xlabel(r'$Column$') fig.colorbar(cax,ax=ax) name = 'noisewidth_auto_individual' - fig.savefig(os.path.join(plot_dir, "{}.pdf".format(name))) - fig.savefig(os.path.join(plot_dir, "{}.png".format(name))) + fig.savefig(os.path.join(result_dir, "{}.pdf".format(name))) + fig.savefig(os.path.join(result_dir, "{}.png".format(name))) + + with open(f'{result_dir}/thresholds.yaml', 'w') as f: + dump((baseline+noise_width).tolist(), f) - if args.scan == 'full': + elif args.threshold == "manual": # Prescanning a random pixel to get an idea of the threshold row = 4 @@ -759,13 +777,13 @@ if __name__ == '__main__': cax2 = ax[1].matshow(noise_matrix) fig.colorbar(cax1,ax=ax[0]) fig.colorbar(cax2,ax=ax[1]) - + ax[0].set_xticks(np.arange(N_pix_w)) ax[0].set_yticks(np.arange(N_pix_w)) ax[1].set_xticks(np.arange(N_pix_w)) ax[1].set_yticks(np.arange(N_pix_w)) - + for i in range(N_pix_w): for j in range(N_pix_w): text = ax[0].text(j, i, int(max_matrix[i,j]), @@ -773,9 +791,8 @@ if __name__ == '__main__': text1 = ax[1].text(j, i, int(noise_matrix[i,j]), ha="center", va="center", color="w", fontsize="xx-small") - - #fig.savefig(f'results/peak_thresholds.png') - fig.savefig(f'results/peak_and_noiseWidth_thresholds.png') + + fig.savefig(f'{result_dir}/peak_and_noiseWidth_thresholds.png') plt.show() plt.close(fig) @@ -797,16 +814,26 @@ if __name__ == '__main__': ax.set_xlabel("Column") ax.set_ylabel("Row") - fig.savefig(f'results/thresholds.png') + fig.savefig(f'{result_dir}/thresholds.png') plt.show() plt.close(fig) del fig, ax - with open('results/thresholds.yaml', 'w') as f: + with open(f'{result_dir}/thresholds.yaml', 'w') as f: dump(threshold_matrix.tolist(), f) - elif args.scan == 'simple': + else: + + print(f"Trying to load tresholds from the following file: {args.threshold}") + with open(f'{result_dir}/thresholds.yaml', 'r') as f: + threshold_matrix = load(f) + + for row in range(16): + for col in range(16): + etroc.wr_reg('DAC', threshold_matrix[row][col], row=row, col=col) + + if args.pixelscan == 'simple': row = 4 col = 3 @@ -849,7 +876,7 @@ if __name__ == '__main__': print(vth) print(count) - elif args.scan =="internal": + elif args.pixelscan =="internal": row = int(args.row) col = int(args.col) @@ -907,7 +934,7 @@ if __name__ == '__main__': plt.legend() now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") - fig.savefig(f'results/scan_internal_row_{row}_col_{col}_{now}.png') + fig.savefig(f'{result_dir}/scan_internal_row_{row}_col_{col}_{now}.png') if args.internal_data: # this still gives type == 0 data (with TOA, TOT, CAL) @@ -988,8 +1015,6 @@ if __name__ == '__main__': if args.qinj: etroc.reset() etroc.wr_reg("disDataReadout", 1, broadcast=True) - with open('results/thresholds.yaml', 'r') as f: - threshold_matrix = load(f, Loader) N_pix = 16*16 # total # of pixels N_pix_w = 16 # N_pix in NxN layout @@ -1022,7 +1047,6 @@ if __name__ == '__main__': charge = int(args.charge) - 1 for row, col in pixels: etroc.wr_reg("disDataReadout", 0, row=row, col=col, broadcast=False) - etroc.wr_reg("DAC", int(threshold_matrix[row][col]), row=row, col=col) etroc.wr_reg("QSel", charge, row=row, col=col) etroc.wr_reg("QInjEn", 1, row=row, col=col) -- GitLab From 123379d2b17e1e4f2128c9d2dbf2fe037c7091b3 Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Mon, 6 Nov 2023 16:08:51 -0500 Subject: [PATCH 2/4] fix it for software emulator / CI --- test_ETROC.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test_ETROC.py b/test_ETROC.py index d6ecd07..9716704 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -158,8 +158,11 @@ if __name__ == '__main__': argParser.add_argument('--moduleid', action='store', default=0, help="") args = argParser.parse_args() - assert int(args.moduleid)>0, "Module ID is not specified. This is a new feature, please run with --moduleid MODULEID, where MODULEID is the number on the module test board." - MID = args.moduleid + if args.test_chip or args.config_chip: + assert int(args.moduleid)>0, "Module ID is not specified. This is a new feature, please run with --moduleid MODULEID, where MODULEID is the number on the module test board." + MID = args.moduleid + else: + MID = "software" timestamp = time.time() -- GitLab From e0a361012d422267bc2061a7b450f7ab28f35398 Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Tue, 7 Nov 2023 12:43:28 -0500 Subject: [PATCH 3/4] making output more verbose, fixing minor issues. tested with module v0b --- test_ETROC.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/test_ETROC.py b/test_ETROC.py index 9716704..f2fb427 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -146,9 +146,9 @@ if __name__ == '__main__': argParser.add_argument('--charge', action='store', default=15, help="Charge to be injected") argParser.add_argument('--hard_reset', action='store_true', default=False, help="Hard reset of selected ETROC2 chip") argParser.add_argument('--skip_sanity_checks', action='store_true', default=False, help="Don't run sanity checks of ETROC2 chip") - argParser.add_argument('--scan', action='store', default=['full'], choices=['none', 'full', 'simple', 'internal'], help="Which threshold scan to run with ETROC2") - argParser.add_argument('--mode', action='store', default=['dual'], choices=['dual', 'single'], help="Port mode for ETROC2") - argParser.add_argument('--threshold', action='store', default=['manual'], choices=['manual', 'auto'], help="Use thresholds from manual or automatic scan?") + argParser.add_argument('--pixelscan', action='store', default='none', choices=['none', 'full', 'simple', 'internal'], help="Which threshold scan to run with ETROC2") + argParser.add_argument('--mode', action='store', default='dual', choices=['dual', 'single'], help="Port mode for ETROC2") + argParser.add_argument('--threshold', action='store', default='auto', help="Use thresholds from manual or automatic scan?") argParser.add_argument('--internal_data', action='store_true', help="Set up internal data generation") argParser.add_argument('--enable_power_board', action='store_true', help="Enable Power Board (all modules). Jumpers must still be set as well.") argParser.add_argument('--timing_scan', action='store_true', help="Perform L1Adelay timing scan") @@ -164,7 +164,7 @@ if __name__ == '__main__': else: MID = "software" - timestamp = time.time() + timestamp = time.strftime("%Y-%m-%d-%H-%M-%S") result_dir = f"results/{MID}/{timestamp}/" out_dir = f"outputs/{MID}/{timestamp}/" @@ -550,7 +550,7 @@ if __name__ == '__main__': ) name = 'hit_matrix_internal_test_pattern' fig.savefig(os.path.join(result_dir, f"{name}.pdf")) - fig.savefig(os.path.join(tesult_dir, f"{name}.png")) + fig.savefig(os.path.join(result_dir, f"{name}.png")) fifo.reset() print("\n - Testing fast command communication - Sending two L1As") @@ -576,7 +576,7 @@ if __name__ == '__main__': #etroc.QInj_set(30, 0, row=3, col=3, broadcast=False) start_time = time.time() - with tqdm(total=65536) as pbar: + with tqdm(total=65536, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}') as pbar: while not fifo.is_full(): fifo.send_l1a() #fifo.send_QInj(delay=j) @@ -666,13 +666,24 @@ if __name__ == '__main__': fig.savefig(os.path.join(plot_dir, "{}.png".format(name))) # not using broadcast - print ("Using auto-threshold calibration for individual pixels") + print ("\n - Using auto-threshold calibration for individual pixels") baseline = np.empty([16, 16]) noise_width = np.empty([16, 16]) - for i in range(16): - for j in range(16): - baseline[i][j], noise_width[i][j] = etroc.auto_threshold_scan(row=i, col=j, broadcast=False) - + #pixel = 0 + with tqdm(total=255, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}') as pbar: + for pixel in range(256): + row = pixel & 0xF + col = (pixel & 0xF0) >> 4 + #print(pixel, row, col) + baseline[row][col], noise_width[row][col] = etroc.auto_threshold_scan(row=row, col=col, broadcast=False) + #print(pixel) + pbar.update() + #pbar.close() + #pixel += 1 + #for i, j in pixels: in range(16): + # for j in range(16): + + print ("Done with threshold scan") fig, ax = plt.subplots(1,1,figsize=(7,7)) cax = ax.matshow(baseline) ax.set_ylabel(r'$Row$') @@ -1087,7 +1098,7 @@ if __name__ == '__main__': text = ax.text(j, i, int(hit_matrix[i,j]), ha="center", va="center", color="w", fontsize="xx-small") - fig.savefig(f'results/hit_matrix.png') + fig.savefig(f'{result_dir}/hit_matrix_qinj.png') plt.show() plt.close(fig) @@ -1096,7 +1107,7 @@ if __name__ == '__main__': import struct fifo.reset() - with open(f"output/output_qinj_{args.charge}fC.dat", mode="wb") as f: + with open(f"{out_dir}/output_qinj_{args.charge}fC.dat", mode="wb") as f: for i in range(50): fifo.send_QInj(1000, delay=etroc.QINJ_delay) data = fifo.read(dispatch=True) -- GitLab From 1f8174c5111bfbf42d6366eb88051ad29834f15b Mon Sep 17 00:00:00 2001 From: dspitzba <daniel.spitzbart@cern.ch> Date: Wed, 8 Nov 2023 10:48:08 -0500 Subject: [PATCH 4/4] fix progress bar --- test_ETROC.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_ETROC.py b/test_ETROC.py index f2fb427..b5160e2 100644 --- a/test_ETROC.py +++ b/test_ETROC.py @@ -670,7 +670,7 @@ if __name__ == '__main__': baseline = np.empty([16, 16]) noise_width = np.empty([16, 16]) #pixel = 0 - with tqdm(total=255, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}') as pbar: + with tqdm(total=256, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}') as pbar: for pixel in range(256): row = pixel & 0xF col = (pixel & 0xF0) >> 4 -- GitLab