#!/bin/env python3
# written 2019-01-28 by mza
# last updated 2023-09-26 by mza
import threading # Thread()
from math import *
from B2L_common import *
from B2L_defs import *
from get_status import get_status
import ethudp
from DebugInfoWarningError import debug, info, warning, error, debug2, debug3, set_verbosity
import time # sleep()
import struct # unpack_from
import pytz # pytz - sudo apt install -y python-pip; sudo pip2 install pytz
#import datetime
import matplotlib.dates as mdates # sudo pip2 install matplotlib
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from math import ceil
# sudo apt install -y python-pip python3-pip python-tk
# python -m pip install --user -U pip
# python -m pip install --user -U matplotlib
# python -m pip install --user -U scipy
import matplotlib.pyplot as plt # sudo apt install -y python-cairocffi
import matplotlib.gridspec as gridspec
#import matplotlib.image as mpl_img
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter, AutoMinorLocator)
import numpy
import tkinter # sudo apt install -y python3-tk
from PIL import Image, ImageTk # sudo apt-get install -y python3-pil.imagetk
def print_ROOT_usage():
print("ROOT environment not setup yet")
HOME = os.environ['HOME']
potential_locations = [ "/usr/local/bin", HOME + "/build/root/bin" ]
filename = "thisroot.sh"
for location in potential_locations:
potential_filename = location + "/" + filename
if os.path.isfile(potential_filename):
#print(". " + HOME + "/build/root/bin/thisroot.sh; " + str(sys.argv))
print(". " + potential_filename)
#info(sys.argv[0] + sys.argv[1:])
#info(" ".join(sys.argv[0:]))
sys.exit(1)
try:
import ROOT # TH1F
info("using ROOT")
should_use_ROOT = True
except:
should_use_ROOT = False
info("not using ROOT")
#print_ROOT_usage()
#ROOT.gROOT.SetBatch(True)
BS = 0
frame_mask_shift = 16
frame_mask_all = 0b111111111 << frame_mask_shift
bunch_marker_first_valid = 4
initial_bunch_marker_of_interest = 1701
desired_RF_bucket = initial_bunch_marker_of_interest
RF_buckets = 5120
bunch_marker_last_valid = RF_buckets - 1
#number_of_64_sample_windows_per_beam_orbit = 427
pedestal_subtraction_amount = 1000
stagger_amount = 50
ch_adc_min = 0 - 300
ch_adc_max = 128 * stagger_amount + 300
maximum_absolute_value_before_issuing_warning = 1000
slice_lower_limit = -250
slice_upper_limit = 300
should_plot_slice = 0
#should_plot_sweep = 1
#should_plot_zoomed_waveforms = 1
#number_of_zoomed_waveforms_to_plot = 4
should_generate_png = 1
should_generate_pdf = 0
gui_update_period_ms = 200
linewidth = 0.3
dpi = 100.0
duration_in_ns_of_64_sample_waveform = 23.58
desired_x_axis = "time"
desired_physical_window_numbers = [ w for w in range(425) ]
starting_physical_window_number = 0
ending_physical_window_number = starting_physical_window_number + 425
revolution_marker_offset_in_RF_buckets = 4370.5
bunch_current_offset = -260.0
bunch_current_scale = 350.0
current_gridstep = 200.0 # in mA
nbunches_gridstep = 400
def set_trigger_mask(s, c0, c1, c2, c3):
write_register(SCROD_AxiCommon_trigMask, s, BS)
write_register(CARRIER_AxiCommon_trigMask, c0, BS, 0)
write_register(CARRIER_AxiCommon_trigMask, c1, BS, 1)
write_register(CARRIER_AxiCommon_trigMask, c2, BS, 2)
write_register(CARRIER_AxiCommon_trigMask, c3, BS, 3)
def mask_triggers(s=0xf, c0=0xf, c1=0xf, c2=0xf, c3=0xf):
set_trigger_mask(s, c0, c1, c2, c3)
def unmask_triggers(s=0, c0=0, c1=0, c2=0, c3=0):
set_trigger_mask(s, c0, c1, c2, c3)
def set_trig_prescale_N_log2(N_log2):
write_register(SCROD_AxiCommon_trig_prescale_N_log2, N_log2, BS)
def get_xrm_trigger_enable_status():
return read_register(SCROD_AxiCommon_xrm_trigger_enabled, BS)
def enable_xrm_triggers():
write_register(SCROD_AxiCommon_xrm_trigger_enabled, 1, BS)
def disable_xrm_triggers():
write_register(SCROD_AxiCommon_xrm_trigger_enabled, 0, BS)
def allow_xrm_triggers_for_a_while(duration=1.0):
if be_verbose_when_collecting_data:
info("allowing xrm triggers for " + str(int(1000.0*duration)/1000.0) + " seconds...")
a = get_SCROD_eventCnt()
enable_xrm_triggers()
time.sleep(duration)
disable_xrm_triggers()
b = get_SCROD_eventCnt()
diff = b - a
info("eventCnt difference: " + str(diff))
return diff
def trigger_and_wait_for_xrm_triggers(duration=1.0):
# if be_verbose_when_collecting_data:
# info("allowing xrm triggers for " + str(int(1000.0*duration)/1000.0) + " seconds...")
a = get_SCROD_eventCnt()
if should_software_trigger:
software_trigger(BS)
else:
write_register_without_readback_verification(SCROD_AxiCommon_clear_count_of_triggers_for_bunch_markers, 0xf, BS)
wait_at_least_until_next_frame9()
time.sleep(duration)
b = get_SCROD_eventCnt()
diff = b - a
info("eventCnt difference: " + str(diff))
return diff
expected_trigger_rate = { 0:11150.0, 1:5560.0, 2:2780.0, 3:1390.0, 4:690.0, 5:350.0, 6:170.0, 7:90.0, 8:40.0, 9:20.0, 10:10.0, 11:5.0, 12:2.0, 13:1.0, 14:1.0, 15:1.0, 16:1.0, 17:1.0, 18:1.0 }
def generate_histogram_of_trigger_rate_versus_prescale_N_log2(start, end):
global expected_trigger_rate
old_desired_trigger_quantities = set_desired_trigger_quantities(0, 0, 0, 0)
mask_triggers()
#max_rate = 151000.0
for i in range(start, end+1):
set_trig_prescale_N_log2(i)
#duration = 40.0 * (2.0**i) / max_rate
duration = 0.1
#info(duration)
if i > 10:
duration = 1.0
diff = allow_xrm_triggers_for_a_while(duration)
#info(str(diff))
rate = diff / duration
expected_trigger_rate[i] = rate
info("[" + str(i) + "]: " + str(rate))
set_desired_trigger_quantities(old_desired_trigger_quantities[0], old_desired_trigger_quantities[1], old_desired_trigger_quantities[2], old_desired_trigger_quantities[3])
def get_SCROD_eventCnt(should_show_it=0):
SCROD_eventCnt = read_register(SCROD_AxiCommon_eventCnt, BS)
if should_show_it:
info("SCROD_eventCnt: " + str(SCROD_eventCnt))
return SCROD_eventCnt
def get_carrier_eventCnts(should_show_them=0):
if 5==number_of_carriers[BS] or 0==number_of_carriers[BS]:
return
eventCnt = []
if 1 <= number_of_carriers[BS]:
carrier0_eventCnt = read_register(CARRIER_AxiCommon_eventCnt, BS, 0)
eventCnt.append(carrier0_eventCnt)
if should_show_them:
info("carrier0_eventCnt: " + str(carrier0_eventCnt))
if 2 <= number_of_carriers[BS]:
carrier1_eventCnt = read_register(CARRIER_AxiCommon_eventCnt, BS, 1)
eventCnt.append(carrier1_eventCnt)
if should_show_them:
info("carrier1_eventCnt: " + str(carrier1_eventCnt))
if 3 <= number_of_carriers[BS]:
carrier2_eventCnt = read_register(CARRIER_AxiCommon_eventCnt, BS, 2)
eventCnt.append(carrier2_eventCnt)
if should_show_them:
info("carrier2_eventCnt: " + str(carrier2_eventCnt))
if 4 <= number_of_carriers[BS]:
carrier3_eventCnt = read_register(CARRIER_AxiCommon_eventCnt, BS, 3)
eventCnt.append(carrier3_eventCnt)
if should_show_them:
info("carrier3_eventCnt: " + str(carrier3_eventCnt))
return eventCnt
def set_desired_trigger_quantities(a, b, c, d):
old_a = read_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_a, BS)
old_b = read_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_b, BS)
old_c = read_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_c, BS)
old_d = read_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_d, BS)
write_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_a, a, BS)
write_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_b, b, BS)
write_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_c, c, BS)
write_register(SCROD_AxiCommon_desired_trigger_quantity_for_bunch_marker_d, d, BS)
return old_a, old_b, old_c, old_d
def calculate_parameters(SST_clock_divide_ratio=6, should_print_info=0):
# 5120 / 4 = 1280 FTSW clocks per frame
# 5120 buckets / 508.8875 MHz = 10.0611628307 us per frame
#
# 127.221875 MHz / 6 = 21.203645833 MHz
# 128 samples per write window * 21.203645833 MHz SST = 2714.066666 MHz sampling rate
# 1/21.203645833 MHz = 47.1617007689 ns per write window
# 10.0611628307 us / 47.1617007689 ns = 213.333333 write windows per revolution
# 5120 / 213.333333 = 24.0 bunches per window
# 6.0 FTSW bunches per window
#
# 127.221875 MHz / 8 = 15.902734375 MHz
# 128 samples per write window * 15.902734375 MHz SST = 2035.55 MHz sampling rate
# 1/15.902734375 MHz = 62.882268 ns per write window
# 10.0611628307 us / 62.882268 ns = 160 write windows per revolution
# 5120 / 160 = 32.0 bunches per window
# 8.0 FTSW bunches per window
global RF_clock_Hz
RF_clock_Hz = 508.8875e6
global period_of_RF_clock_ns
period_of_RF_clock_ns = 1.0e9 / RF_clock_Hz
global asic_samples_per_write_window
asic_samples_per_write_window = 128
global asic_samples_per_read_window
asic_samples_per_read_window = asic_samples_per_write_window // 2
global FTSW_clock_divide_ratio
FTSW_clock_divide_ratio = 4
global revolution_duration_s
revolution_duration_s = RF_buckets / RF_clock_Hz
global SST_clock_Hz
SST_clock_Hz = RF_clock_Hz / FTSW_clock_divide_ratio / SST_clock_divide_ratio
global sampling_rate_Hz
sampling_rate_Hz = SST_clock_Hz * asic_samples_per_write_window
global write_window_duration_s
write_window_duration_s = 1.0 / SST_clock_Hz
global read_window_duration_s
read_window_duration_s = write_window_duration_s / 2.0
global write_windows_per_revolution
write_windows_per_revolution = revolution_duration_s / write_window_duration_s
global read_windows_per_revolution
read_windows_per_revolution = revolution_duration_s / read_window_duration_s
global RF_buckets_per_write_window
RF_buckets_per_write_window = RF_buckets // write_windows_per_revolution
global RF_buckets_per_read_window
RF_buckets_per_read_window = RF_buckets // read_windows_per_revolution
global FTSW_clocks_per_write_window
FTSW_clocks_per_write_window = RF_buckets_per_write_window // FTSW_clock_divide_ratio
global FTSW_clocks_per_read_window
FTSW_clocks_per_read_window = RF_buckets_per_read_window // FTSW_clock_divide_ratio
global asic_samples_per_RF_bucket
asic_samples_per_RF_bucket = asic_samples_per_read_window // RF_buckets_per_read_window
global total_number_of_physical_windows
total_number_of_physical_windows = 512
if should_print_info:
info("revolution_duration_us: " + str(revolution_duration_s*1.0e6))
info("SST_clock_MHz: " + str(SST_clock_Hz/1.0e6))
info("sampling_rate_GHz: " + str(sampling_rate_Hz/1.0e9))
info("write_window_duration_ns : " + str(write_window_duration_s*1.0e9))
info("read_window_duration_ns : " + str(read_window_duration_s*1.0e9))
info("write_windows_per_revolution: " + str(write_windows_per_revolution))
info("read_windows_per_revolution: " + str(read_windows_per_revolution))
info("RF_buckets_per_write_window: " + str(RF_buckets_per_write_window))
info("RF_buckets_per_read_window: " + str(RF_buckets_per_read_window))
info("FTSW_clocks_per_write_window: " + str(FTSW_clocks_per_write_window))
info("FTSW_clocks_per_read_window: " + str(FTSW_clocks_per_read_window))
def show_xrm_trigger_enable_status():
en = read_register(SCROD_AxiCommon_xrm_trigger_enabled, BS)
info("xrm trigger enabled: " + str(en))
def show_relevant_registers():
#get_SCROD_eventCnt(1)
#get_carrier_eventCnts(1)
show_frame_masks()
nlog2 = read_register(SCROD_AxiCommon_trig_prescale_N_log2, BS)
info("N_log2 prescale: " + str(nlog2))
show_xrm_trigger_enable_status()
show_asic_timeouts(BS)
show_SEM_status(BS)
def show_some_info():
info("")
show_current_time()
show_asic_timeouts(BS)
get_SCROD_eventCnt(1)
get_carrier_eventCnts(1)
show_relevant_registers()
... 3541 more lines ...
|