def configure(self): commands = [] commands.extend(self.register.get_commands("ConfMode")) # Enable enable_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span) if not self.overwrite_enable_mask: enable_pixel_mask = np.logical_and(enable_pixel_mask, self.register.get_pixel_register_value('Enable')) self.register.set_pixel_register_value('Enable', enable_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) # Imon if self.use_enable_mask_for_imon: imon_pixel_mask = invert_pixel_mask(enable_pixel_mask) else: imon_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span, default=1, value=0) # 0 for selected columns, else 1 imon_pixel_mask = np.logical_or(imon_pixel_mask, self.register.get_pixel_register_value('Imon')) self.register.set_pixel_register_value('Imon', imon_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Imon')) # C_High self.register.set_pixel_register_value('C_High', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_High')) # C_Low self.register.set_pixel_register_value('C_Low', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_Low')) # Registers self.register.set_global_register_value("Trig_Lat", self.trigger_latency) # set trigger latency self.register.set_global_register_value("Trig_Count", self.trig_count) # set number of consecutive triggers commands.extend(self.register.get_commands("WrRegister", name=["Trig_Lat", "Trig_Count"])) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_tot_hist = True if self.enable_tdc: analyze_raw_data.create_tdc_counter_hist = True # histogram all TDC words analyze_raw_data.create_tdc_hist = True # histogram the hit TDC information analyze_raw_data.interpreter.use_tdc_word(True) # align events at the TDC word analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > 0] = 1 plot_occupancy(occ_mask.T, title='Merged Pixels', z_max=1, filename=analyze_raw_data.output_pdf) inv_occ_mask = invert_pixel_mask(occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and(inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or(occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask)
def configure(self): commands = [] commands.extend(self.register.get_commands("ConfMode")) # Enable enable_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span) if not self.overwrite_enable_mask: enable_pixel_mask = np.logical_and(enable_pixel_mask, self.register.get_pixel_register_value('Enable')) self.register.set_pixel_register_value('Enable', enable_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) # Imon if self.use_enable_mask_for_imon: imon_pixel_mask = invert_pixel_mask(enable_pixel_mask) else: imon_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span, default=1, value=0) # 0 for selected columns, else 1 imon_pixel_mask = np.logical_or(imon_pixel_mask, self.register.get_pixel_register_value('Imon')) self.register.set_pixel_register_value('Imon', imon_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Imon')) # C_High self.register.set_pixel_register_value('C_High', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_High')) # C_Low self.register.set_pixel_register_value('C_Low', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_Low')) # Registers self.register.set_global_register_value("Trig_Lat", self.trigger_latency) # set trigger latency self.register.set_global_register_value("Trig_Count", 1) # set number of consecutive triggers commands.extend(self.register.get_commands("WrRegister", name=["Trig_Lat", "Trig_Count"])) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands)
def scan(self): delay_parameter_name = self.scan_parameters._fields[1] logging.info( "Scanning PlsrDAC = %s and %s = %s", str(self.scan_parameters[0]), delay_parameter_name, str(self.scan_parameters[1]), ) plsr_dac_values = self.scan_parameters.PlsrDAC[ : ] # create deep copy of scan_parameters, they are overwritten in self.readout delay_parameter_values = self.scan_parameters.PlsrDelay[ : ] # create deep copy of scan_parameters, they are overwritten in self.readout for plsr_dac_value in plsr_dac_values: # Change the Plsr DAC parameter commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value("PlsrDAC", plsr_dac_value) commands.extend(self.register.get_commands("WrRegister", name=["PlsrDAC"])) self.register_utils.send_commands(commands) for delay_parameter_value in delay_parameter_values: # Loop over the Plsr delay parameter if self.stop_run.is_set(): break # Change the Plsr delay parameter commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value(delay_parameter_name, delay_parameter_value) commands.extend(self.register.get_commands("WrRegister", name=[delay_parameter_name])) self.register_utils.send_commands(commands) with self.readout(plsr_dac_value, delay_parameter_value): cal_lvl1_command = ( self.register.get_commands("CAL")[0] + self.register.get_commands("zeros", length=40)[0] + self.register.get_commands("LV1")[0] ) scan_loop( self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value("Enable")) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction, )
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_source_scan_hist = True analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_tot_hist = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() # occ_hist = make_occupancy_hist(*convert_data_array(data_array_from_data_dict_iterable(self.fifo_readout.data), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array)).T with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 self.occ_mask[occ_hist < self.n_injections] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) self.disable_for_mask = self.disable_for_mask if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value( mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) self.enable_for_mask = self.enable_for_mask if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Stuck Pixels', z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_source_scan_hist = True analyze_raw_data.create_hit_table = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 self.occ_mask[occ_hist > self.abs_occ_limit] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value( mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Noisy Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(self.occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def scan(self): with self.readout(): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] if self.enable_tdc: # activate TDC arming self.dut['tdc_rx2']['EN_ARMING'] = True scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, bol_function=self.activate_tdc, eol_function=self.deactivate_tdc, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction) else: scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def scan(self): delay_parameter_name = self.scan_parameters._fields[1] logging.info("Scanning PlsrDAC = %s and %s = %s" % (str(self.scan_parameters[0]), delay_parameter_name, str(self.scan_parameters[1]))) plsr_dac_values = self.scan_parameters.PlsrDAC[:] # create deep copy of scan_parameters, they are overwritten in self.readout delay_parameter_values = self.scan_parameters.PlsrDelay[:] # create deep copy of scan_parameters, they are overwritten in self.readout for plsr_dac_value in plsr_dac_values: # Change the Plsr DAC parameter commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', plsr_dac_value) commands.extend( self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) for delay_parameter_value in delay_parameter_values: # Loop over the Plsr delay parameter if self.stop_run.is_set(): break logging.info('Scan step: PlsrDAC %s, %s %d' % (plsr_dac_value, delay_parameter_name, delay_parameter_value)) # Change the Plsr delay parameter commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value( delay_parameter_name, delay_parameter_value) commands.extend( self.register.get_commands("WrRegister", name=[delay_parameter_name])) self.register_utils.send_commands(commands) with self.readout(plsr_dac_value, delay_parameter_value): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40 )[0] + self.register.get_commands("LV1")[0] scan_loop( self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_tot_hist = True if self.enable_tdc: analyze_raw_data.create_tdc_counter_hist = True # histogram all TDC words analyze_raw_data.create_tdc_hist = True # histogram the hit TDC information analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() occ_hist = analyze_raw_data.out_file_h5.root.HistOcc[:, :, 0].T occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > 1] = 1 inv_occ_mask = invert_pixel_mask(occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(occ_mask.T, title='Merged Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def scan(self): scan_parameter_range = [ 0, (2**self.register.global_registers['PlsrDAC']['bitlength']) ] if self.scan_parameters.PlsrDAC[0]: scan_parameter_range[0] = self.scan_parameters.PlsrDAC[0] if self.scan_parameters.PlsrDAC[1]: scan_parameter_range[1] = self.scan_parameters.PlsrDAC[1] scan_parameter_range = range(scan_parameter_range[0], scan_parameter_range[1] + 1, self.step_size) logging.info( "Scanning %s from %d to %d" % ('PlsrDAC', scan_parameter_range[0], scan_parameter_range[-1])) for scan_parameter_value in scan_parameter_range: if self.stop_run.is_set(): break logging.info('Scan step: %s %d' % ('PlsrDAC', scan_parameter_value)) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', scan_parameter_value) commands.extend( self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) with self.readout(PlsrDAC=scan_parameter_value): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_source_scan_hist = True analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_tot_hist = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() occ_hist = analyze_raw_data.out_file_h5.root.HistOcc[:, :, 0].T occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 occ_mask[occ_hist < self.n_injections] = 1 # make inverse inv_occ_mask = invert_pixel_mask(occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(occ_mask.T, title='Stuck Pixels', z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def scan(self): scan_parameter_name = self.scan_parameters._fields[ -1] # scan parameter is in inner loop scan_parameters_values = self.scan_parameters[ -1][:] # create deep copy of scan_parameters, they are overwritten in self.readout logging.info("Scanning %s from %d to %d", scan_parameter_name, scan_parameters_values[0], scan_parameters_values[-1]) for scan_parameter_value in scan_parameters_values: if self.stop_run.is_set(): break commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value(scan_parameter_name, scan_parameter_value) commands.extend( self.register.get_commands("WrRegister", name=[scan_parameter_name])) self.register_utils.send_commands(commands) with self.readout(**{scan_parameter_name: scan_parameter_value}): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, fast_dc_loop=True, bol_function=None, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_cluster_size_hist = False analyze_raw_data.create_source_scan_hist = True analyze_raw_data.create_cluster_tot_hist = False analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.clusterizer.set_warning_output(False) analyze_raw_data.interpret_word_table() analyze_raw_data.interpreter.print_summary() analyze_raw_data.plot_histograms() with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # n largest elements n_largest_elements = np.sort(occ_hist[occ_hist > self.low_value])[-self.mask_high_count:] # noisy pixels are set to 1 if n_largest_elements.shape[0] > 0: self.occ_mask[occ_hist >= n_largest_elements[0]] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and(self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or(self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Noisy Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(self.occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_source_scan_hist = True analyze_raw_data.create_hit_table = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 if self.trig_count == 0: consecutive_lvl1 = (2 ** self.register.global_registers['Trig_Count']['bitlength']) else: consecutive_lvl1 = self.trig_count self.occ_mask[occ_hist > self.occupancy_limit * self.n_triggers * consecutive_lvl1] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and(self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or(self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Noisy Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(self.occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_tot_hist = True if self.enable_tdc: analyze_raw_data.create_tdc_counter_hist = True # histogram all TDC words analyze_raw_data.create_tdc_hist = True # histogram the hit TDC information analyze_raw_data.interpreter.use_tdc_word( True) # align events at the TDC word analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > 0] = 1 plot_occupancy(occ_mask.T, title='Merged Pixels', z_max=1, filename=analyze_raw_data.output_pdf) inv_occ_mask = invert_pixel_mask(occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_source_scan_hist = True analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_tot_hist = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() # occ_hist = make_occupancy_hist(*convert_data_array(data_array_from_data_dict_iterable(self.fifo_readout.data), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array)).T with tb.open_file(analyze_raw_data._analyzed_data_file, 'r') as out_file_h5: occ_hist = out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 self.occ_mask[occ_hist < self.n_injections] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) self.disable_for_mask = self.disable_for_mask if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and(self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) self.enable_for_mask = self.enable_for_mask if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or(self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Stuck Pixels', z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def scan(self): with self.readout(): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, eol_function=None, digital_injection=True, enable_shift_masks=["Enable", "EnableDigInj"], restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None)
def configure(self): if self.trig_count == 0: self.consecutive_lvl1 = (2 ** self.register.global_registers['Trig_Count']['bitlength']) else: self.consecutive_lvl1 = self.trig_count self.abs_occ_limit = int(self.occupancy_limit * self.n_triggers * self.consecutive_lvl1) if self.abs_occ_limit < 1.0: logging.warning('Number of triggers too low for given occupancy limit. Any hit will result in a masked pixel.') else: logging.info('Masking pixels with occupancy >%d (sending %d triggers)', self.abs_occ_limit, self.n_triggers) commands = [] commands.extend(self.register.get_commands("ConfMode")) # Enable enable_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span) if not self.overwrite_enable_mask: enable_pixel_mask = np.logical_and(enable_pixel_mask, self.register.get_pixel_register_value('Enable')) self.register.set_pixel_register_value('Enable', enable_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) # Imon if self.use_enable_mask_for_imon: imon_pixel_mask = invert_pixel_mask(enable_pixel_mask) else: imon_pixel_mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span, default=1, value=0) # 0 for selected columns, else 1 imon_pixel_mask = np.logical_or(imon_pixel_mask, self.register.get_pixel_register_value('Imon')) self.register.set_pixel_register_value('Imon', imon_pixel_mask) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Imon')) # C_High self.register.set_pixel_register_value('C_High', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_High')) # C_Low self.register.set_pixel_register_value('C_Low', 0) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name='C_Low')) # Registers # self.register.set_global_register_value("Trig_Lat", self.trigger_latency) # set trigger latency self.register.set_global_register_value("Trig_Count", self.trig_count) # set number of consecutive triggers commands.extend(self.register.get_commands("WrRegister", name=["Trig_Count"])) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands)
def scan(self): scan_parameter_range = [0, (2 ** self.register.global_registers['PlsrDAC']['bitlength'])] if self.scan_parameters.PlsrDAC[0]: scan_parameter_range[0] = self.scan_parameters.PlsrDAC[0] if self.scan_parameters.PlsrDAC[1]: scan_parameter_range[1] = self.scan_parameters.PlsrDAC[1] scan_parameter_range = range(scan_parameter_range[0], scan_parameter_range[1] + 1, self.step_size) logging.info("Scanning %s from %d to %d", 'PlsrDAC', scan_parameter_range[0], scan_parameter_range[-1]) for scan_parameter_value in scan_parameter_range: if self.stop_run.is_set(): break commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', scan_parameter_value) commands.extend(self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) with self.readout(PlsrDAC=scan_parameter_value): cal_lvl1_command = self.register.get_commands("CAL")[0] + self.register.get_commands("zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, fast_dc_loop=True, bol_function=None, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def scan(self): self.start_condition_triggered = False # set to true if the start condition is true once self.stop_condition_triggered = False # set to true if the stop condition is true once self.start_at = 0.01 # if more than start_at*activated_pixel see at least one hit the precise scanning is started self.stop_at = 0.95 # if more than stop_at*activated_pixel see the maximum numbers of injection, the scan is stopped self.record_data = False # set to true to activate data storage, so far not everything is recorded to ease data analysis scan_parameter_range = [0, (2 ** self.register.global_registers['PlsrDAC']['bitlength'] - 1)] if self.scan_parameters.PlsrDAC[0]: scan_parameter_range[0] = self.scan_parameters.PlsrDAC[0] if self.scan_parameters.PlsrDAC[1]: scan_parameter_range[1] = self.scan_parameters.PlsrDAC[1] logging.info("Scanning %s from %d to %d", 'PlsrDAC', scan_parameter_range[0], scan_parameter_range[1]) self.scan_parameter_value = scan_parameter_range[0] # set to start value self.search_distance = self.search_distance self.data_points = 0 # counter variable to count the data points already recorded, have to be at least minimum_data_ponts # calculate DCs to scan from the columns to ignore enable_double_columns = range(0, 40) if 1 in self.ignore_columns: enable_double_columns.remove(0) if set((78, 79, 80)).issubset(self.ignore_columns): enable_double_columns.remove(39) for double_column in range(1, 39): if set((double_column * 2, (double_column * 2) + 1)).issubset(self.ignore_columns): enable_double_columns.remove(double_column) logging.info("Use DCs: %s", str(enable_double_columns)) self.select_arr_columns = range(0, 80) for column in self.ignore_columns: self.select_arr_columns.remove(column - 1) while self.scan_parameter_value <= scan_parameter_range[1]: # scan as long as scan parameter is smaller than defined maximum if self.stop_run.is_set(): break commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', self.scan_parameter_value) commands.extend(self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) with self.readout(PlsrDAC=self.scan_parameter_value, reset_sram_fifo=True, fill_buffer=True, clear_buffer=True, callback=self.handle_data if self.record_data else None): cal_lvl1_command = self.register.get_commands("CAL")[0] + self.register.get_commands("zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=self.enable_mask_steps, enable_double_columns=enable_double_columns, same_mask_for_all_dc=True, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction) if not self.start_condition_triggered or self.data_points > self.minimum_data_points: # speed up, only create histograms when needed. Python is much too slow here. if not self.start_condition_triggered and not self.record_data: logging.info('Testing for start condition: %s %d', 'PlsrDAC', self.scan_parameter_value) if not self.stop_condition_triggered and self.record_data: logging.info('Testing for stop condition: %s %d', 'PlsrDAC', self.scan_parameter_value) col, row = convert_data_array(data_array_from_data_iterable(self.fifo_readout.data), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array) if np.any(np.logical_and(col < 1, col > 80)) or np.any(np.logical_and(row < 1, row > 336)): # filter bad data records that can happen logging.warning('There are undefined %d data records (e.g. random data)', np.count_nonzero(np.logical_and(col < 1, col > 80)) + np.count_nonzero(np.logical_and(row < 1, row > 336))) col, row = col[np.logical_and(col > 0, col <= 80)], row[np.logical_and(row > 0, row < 336)] occupancy_array = hist_2d_index(col - 1, row - 1, shape=(80, 336)) self.scan_condition(occupancy_array) # start condition is met for the first time if self.start_condition_triggered and not self.record_data: self.scan_parameter_value = self.scan_parameter_value - self.search_distance + self.step_size if self.scan_parameter_value < 0: self.scan_parameter_value = 0 logging.info('Starting threshold scan at %s %d', 'PlsrDAC', self.scan_parameter_value) self.scan_parameter_start = self.scan_parameter_value self.record_data = True continue # saving data if self.record_data: self.data_points = self.data_points + 1 # stop condition is met for the first time if self.stop_condition_triggered and self.record_data: logging.info('Stopping threshold scan at %s %d', 'PlsrDAC', self.scan_parameter_value) break # increase scan parameter value if not self.start_condition_triggered: self.scan_parameter_value = self.scan_parameter_value + self.search_distance else: self.scan_parameter_value = self.scan_parameter_value + self.step_size if self.scan_parameter_value >= scan_parameter_range[1]: logging.warning("Reached maximum of PlsrDAC range... stopping scan")
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.create_cluster_size_hist = False analyze_raw_data.create_source_scan_hist = True analyze_raw_data.create_cluster_tot_hist = False analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.interpret_word_table() analyze_raw_data.interpreter.print_summary() analyze_raw_data.plot_histograms() occ_hist = analyze_raw_data.out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # n largest elements n_largest_elements = np.sort( occ_hist[occ_hist > self.low_value])[-self.mask_high_count:] # noisy pixels are set to 1 if n_largest_elements.shape[0] > 0: self.occ_mask[occ_hist >= n_largest_elements[0]] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value( mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = np.logical_and( self.inv_occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = np.logical_or( self.occ_mask, self.register.get_pixel_register_value(mask)) self.register.set_pixel_register_value(mask, disable_mask) plot_occupancy(self.occ_mask.T, title='Noisy Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(self.occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf)
def scan(self): with self.readout(): cal_lvl1_command = self.register.get_commands("CAL")[0] + self.register.get_commands("zeros", length=40)[0] + self.register.get_commands("LV1")[0] if self.enable_tdc: # activate TDC arming self.dut['TDC']['EN_ARMING'] = True scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=self.same_mask_for_all_dc, bol_function=self.activate_tdc, eol_function=self.deactivate_tdc, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction) else: scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=self.same_mask_for_all_dc, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def analyze(self): with AnalyzeRawData(raw_data_file=self.output_filename, create_pdf=True) as analyze_raw_data: analyze_raw_data.interpreter.set_warning_output(False) analyze_raw_data.create_source_scan_hist = True analyze_raw_data.create_hit_table = False analyze_raw_data.interpret_word_table() analyze_raw_data.plot_histograms() analyze_raw_data.interpreter.print_summary() # get occupancy hist occ_hist = analyze_raw_data.out_file_h5.root.HistOcc[:, :, 0].T self.occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 self.occ_mask[occ_hist > self.abs_occ_limit] = 1 # make inverse self.inv_occ_mask = invert_pixel_mask(self.occ_mask) # generate masked occupancy hist masked_occ_hist = occ_hist.copy() masked_occ_hist[self.occ_mask == 1] = 0 if self.overwrite_mask: for mask in self.disable_for_mask: self.register.set_pixel_register_value(mask, self.inv_occ_mask) else: for mask in self.disable_for_mask: enable_mask = self.register.get_pixel_register_value(mask) new_enable_mask = np.logical_and(self.inv_occ_mask, enable_mask) self.register.set_pixel_register_value(mask, new_enable_mask) if self.overwrite_mask: for mask in self.enable_for_mask: self.register.set_pixel_register_value(mask, self.occ_mask) else: for mask in self.enable_for_mask: disable_mask = self.register.get_pixel_register_value(mask) new_disable_mask = np.logical_or(self.occ_mask, disable_mask) self.register.set_pixel_register_value(mask, new_disable_mask) plot_occupancy(self.occ_mask.T, title='Noisy Pixels', z_max=1, filename=analyze_raw_data.output_pdf) plot_fancy_occupancy(self.occ_mask.T, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.disable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) for mask in self.enable_for_mask: mask_name = self.register.pixel_registers[mask]['name'] plot_occupancy(self.register.get_pixel_register_value(mask).T, title='%s Mask' % mask_name, z_max=1, filename=analyze_raw_data.output_pdf) # adding Poisson statistics plots fig = Figure() FigureCanvas(fig) ax = fig.add_subplot(111) ax.set_title("Hit statistics") hist, bin_edges = np.histogram(occ_hist, bins=np.arange(0, np.max(occ_hist) + 2, 1)) try: _, idx = hist_quantiles(hist, [0.0, 0.9], return_indices=True) except IndexError: idx = [0, 1] bins = np.arange(0, np.maximum(bin_edges[idx[1]], stats.poisson.ppf(0.9999, mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1)) + 2, 1) ax.hist(occ_hist.flatten(), bins=bins, align='left', alpha=0.5, label="Measured occupancy before masking noisy pixels") ax.hist(masked_occ_hist.flatten(), bins=bins, align='left', alpha=0.5, label="Measured occupancy after masking noisy pixels") ax.bar(x=bins[:-1], height=stats.poisson.pmf(k=bins[:-1], mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1) * self.register.get_pixel_register_value("Enable").sum(), alpha=0.5, width=1.0, color="r", label="Expected occupancy (Poisson statistics)") # ax.hist(stats.poisson.rvs(mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1, size=self.register.get_pixel_register_value("Enable").sum()), bins=bins, align='left', alpha=0.5, label="Expected occupancy (Poisson statistics)") ax.set_xlabel('#Hits') ax.set_ylabel('#Pixels') ax.legend() analyze_raw_data.output_pdf.savefig(fig)
def scan(self): scan_parameter_range = [ 0, (2**self.register.global_registers['PlsrDAC']['bitlength']) ] if self.scan_parameters.PlsrDAC[0]: scan_parameter_range[0] = self.scan_parameters.PlsrDAC[0] if self.scan_parameters.PlsrDAC[1]: scan_parameter_range[1] = self.scan_parameters.PlsrDAC[1] scan_parameter_range = range(scan_parameter_range[0], scan_parameter_range[1] + 1, self.step_size) logging.info("Scanning %s from %d to %d", 'PlsrDAC', scan_parameter_range[0], scan_parameter_range[-1]) def set_xtalk_mask(): frame = inspect.currentframe() if frame.f_back.f_locals['index'] == 0: mask = make_pixel_mask( steps=self.mask_steps, shift=frame.f_back.f_locals['mask_step']) mask = make_xtalk_mask(mask) map( lambda mask_name: self.register.set_pixel_register_value( mask_name, mask), self.disable_shift_masks) commands = [] commands.append(self.register.get_commands("ConfMode")[0]) commands.extend( self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, name=self.xtalk_shift_mask, joint_write=True)) commands.append(self.register.get_commands("RunMode")[0]) self.register_utils.send_commands(commands, concatenate=True) for scan_parameter_value in scan_parameter_range: if self.stop_run.is_set(): break commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', scan_parameter_value) commands.extend( self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) with self.readout(PlsrDAC=scan_parameter_value): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=False, fast_dc_loop=False, bol_function=set_xtalk_mask, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction)
def scan(self): self.start_condition_triggered = False # set to true if the start condition is true once self.stop_condition_triggered = False # set to true if the stop condition is true once self.start_at = 0.01 # if more than start_at*activated_pixel see at least one hit the precise scanning is started self.stop_at = 0.95 # if more than stop_at*activated_pixel see the maximum numbers of injection, the scan is stopped self.record_data = False # set to true to activate data storage, so far not everything is recorded to ease data analysis scan_parameter_range = [ 0, (2**self.register.global_registers['PlsrDAC']['bitlength']) ] if self.scan_parameters.PlsrDAC[0]: scan_parameter_range[0] = self.scan_parameters.PlsrDAC[0] if self.scan_parameters.PlsrDAC[1]: scan_parameter_range[1] = self.scan_parameters.PlsrDAC[1] logging.info( "Scanning %s from %d to %d" % ('PlsrDAC', scan_parameter_range[0], scan_parameter_range[1])) self.scan_parameter_value = scan_parameter_range[ 0] # set to start value self.search_distance = self.search_distance self.data_points = 0 # counter variable to count the data points already recorded, have to be at least minimum_data_ponts # calculate DCs to scan from the columns to ignore enable_double_columns = range(0, 40) if 1 in self.ignore_columns: enable_double_columns.remove(0) if set((78, 79, 80)).issubset(self.ignore_columns): enable_double_columns.remove(39) for double_column in range(1, 39): if set((double_column * 2, (double_column * 2) + 1)).issubset(self.ignore_columns): enable_double_columns.remove(double_column) logging.info("Use DCs: %s" % str(enable_double_columns)) self.select_arr_columns = range(0, 80) for column in self.ignore_columns: self.select_arr_columns.remove(column - 1) while self.scan_parameter_value <= scan_parameter_range[ 1]: # scan as long as scan parameter is smaller than defined maximum if self.stop_run.is_set(): break if self.record_data: logging.info( "Scan step %d (%s %d)" % (self.data_points, 'PlsrDAC', self.scan_parameter_value)) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value('PlsrDAC', self.scan_parameter_value) commands.extend( self.register.get_commands("WrRegister", name=['PlsrDAC'])) self.register_utils.send_commands(commands) with self.readout(PlsrDAC=self.scan_parameter_value): cal_lvl1_command = self.register.get_commands( "CAL")[0] + self.register.get_commands( "zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=self.enable_mask_steps, enable_double_columns=enable_double_columns, same_mask_for_all_dc=True, eol_function=None, digital_injection=False, enable_shift_masks=self.enable_shift_masks, disable_shift_masks=self.disable_shift_masks, restore_shift_masks=False, mask=invert_pixel_mask( self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None, double_column_correction=self.pulser_dac_correction) if not self.start_condition_triggered or self.data_points > self.minimum_data_points: # speed up, only create histograms when needed. Python is much too slow here. if not self.start_condition_triggered and not self.record_data: logging.info('Testing for start condition: %s %d' % ('PlsrDAC', self.scan_parameter_value)) if not self.stop_condition_triggered and self.record_data: logging.info('Testing for stop condition: %s %d' % ('PlsrDAC', self.scan_parameter_value)) col, row = convert_data_array( data_array_from_data_iterable(self.fifo_readout.data), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array) # using self written histogrammer in C++ occupancy_array = hist_2d_index(col - 1, row - 1, shape=(80, 336)) # using numpy # occupancy_array = np.histogram2d(col, row, bins=(80, 336), range=[[1, 80], [1, 336]])[0] self.scan_condition(occupancy_array) # start condition is met for the first time if self.start_condition_triggered and not self.record_data: self.scan_parameter_value = self.scan_parameter_value - self.search_distance + self.step_size if self.scan_parameter_value < 0: self.scan_parameter_value = 0 logging.info('Starting threshold scan at %s %d' % ('PlsrDAC', self.scan_parameter_value)) self.scan_parameter_start = self.scan_parameter_value self.record_data = True continue # saving data if self.record_data: self.data_points = self.data_points + 1 self.raw_data_file.append( self.fifo_readout.data, scan_parameters=self.scan_parameters._asdict()) # stop condition is met for the first time if self.stop_condition_triggered and self.record_data: logging.info('Stopping threshold scan at %s %d' % ('PlsrDAC', self.scan_parameter_value)) break # increase scan parameter value if not self.start_condition_triggered: self.scan_parameter_value = self.scan_parameter_value + self.search_distance else: self.scan_parameter_value = self.scan_parameter_value + self.step_size if self.scan_parameter_value >= scan_parameter_range[1]: logging.warning( "Reached maximum of PlsrDAC range... stopping scan")
def scan(self): scan_parameter_range = [ self.register.get_global_register_value("Vthin_AltFine"), 0 ] if self.scan_parameters.Vthin_AltFine[0]: scan_parameter_range[0] = self.scan_parameters.Vthin_AltFine[0] if self.scan_parameters.Vthin_AltFine[1]: scan_parameter_range[1] = self.scan_parameters.Vthin_AltFine[1] steps = 1 if self.scan_parameters.Step: steps = self.scan_parameters.Step lvl1_command = self.register.get_commands( "LV1")[0] + self.register.get_commands( "zeros", length=self.trigger_rate_limit)[0] self.total_scan_time = int(lvl1_command.length() * 25 * (10**-9) * self.n_triggers) disabled_pixels_limit_cnt = int(self.disabled_pixels_limit * 336 * 80) preselected_pixels = invert_pixel_mask( self.register.get_pixel_register_value('Enable')).sum() disabled_pixels = 0 for reg_val in range(scan_parameter_range[0], scan_parameter_range[1] - 1, -1): if self.stop_run.is_set(): break self.register.create_restore_point(name=str(reg_val)) logging.info('Scanning Vthin_AltFine %d' % reg_val) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value( "Vthin_AltFine", reg_val) # set number of consecutive triggers commands.extend( self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) # setting FE into RunMode commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) step = 0 while True: if self.stop_run.is_set(): break step += 1 logging.info('Step %d / %d at Vthin_AltFine %d' % (step, steps, reg_val)) logging.info('Estimated scan time: %ds' % self.total_scan_time) with self.readout(Vthin_AltFine=reg_val, Step=step): got_data = False start = time() self.register_utils.send_command(lvl1_command, repeat=self.n_triggers, wait_for_finish=False, set_length=True, clear_memory=False) while not self.stop_run.wait(0.1): if self.register_utils.is_ready: if got_data: self.progressbar.finish() logging.info('Finished sending %d triggers' % self.n_triggers) break if not got_data: if self.fifo_readout.data_words_per_second() > 0: got_data = True logging.info('Taking data...') self.progressbar = progressbar.ProgressBar( widgets=[ '', progressbar.Percentage(), ' ', progressbar.Bar(marker='*', left='|', right='|'), ' ', progressbar.Timer() ], maxval=self.total_scan_time, poll=10, term_width=80).start() else: try: self.progressbar.update(time() - start) except ValueError: pass self.raw_data_file.append( self.fifo_readout.data, scan_parameters=self.scan_parameters._asdict()) col_arr, row_arr = convert_data_array( data_array_from_data_iterable(self.fifo_readout.data), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array) occ_hist, _, _ = np.histogram2d(col_arr, row_arr, bins=(80, 336), range=[[1, 80], [1, 336]]) occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # noisy pixels are set to 1 occ_mask[occ_hist > self.occupancy_limit * self.n_triggers * self.consecutive_lvl1] = 1 # plot_occupancy(occ_hist.T, title='Occupancy', filename=self.scan_data_filename + '_noise_occ_' + str(reg_val) + '_' + str(step) + '.pdf') tdac_reg = self.register.get_pixel_register_value('TDAC') decrease_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg > 0) disable_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg == 0) enable_reg = self.register.get_pixel_register_value('Enable') enable_mask = np.logical_and( enable_reg, invert_pixel_mask(disable_pixel_mask)) if np.logical_and(occ_mask > 0, enable_reg == 0).sum(): logging.warning('Received data from disabled pixels') # disabled_pixels += disable_pixel_mask.sum() # can lead to wrong values if the enable reg is corrupted disabled_pixels = invert_pixel_mask( enable_mask).sum() - preselected_pixels if disabled_pixels > disabled_pixels_limit_cnt: logging.info( 'Limit of disabled pixels reached: %d (limit %d)... stopping scan' % (disabled_pixels, disabled_pixels_limit_cnt)) self.register.restore(name=str(reg_val)) break else: logging.info('Increasing threshold of %d pixel(s)' % (decrease_pixel_mask.sum(), )) logging.info( 'Disabling %d pixel(s), total number of disabled pixel(s): %d' % (disable_pixel_mask.sum(), disabled_pixels)) tdac_reg[decrease_pixel_mask] -= 1 # TODO self.register.set_pixel_register_value('TDAC', tdac_reg) self.register.set_pixel_register_value( 'Enable', enable_mask) commands = [] commands.extend(self.register.get_commands("ConfMode")) commands.extend( self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='TDAC')) commands.extend( self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) if occ_mask.sum( ) == 0 or step == steps or decrease_pixel_mask.sum( ) < disabled_pixels_limit_cnt: self.register.clear_restore_points(name=str(reg_val)) self.last_tdac_distribution = self.register.get_pixel_register_value( 'TDAC') self.last_occupancy_hist = occ_hist.copy() self.last_occupancy_mask = occ_mask.copy() self.last_reg_val = reg_val self.last_step = step break else: logging.info( 'Found noisy pixels... repeat tuning step for Vthin_AltFine %d' % (reg_val, )) if disabled_pixels > disabled_pixels_limit_cnt: self.last_good_threshold = self.register.get_global_register_value( "Vthin_AltFine") self.last_good_tdac = self.register.get_pixel_register_value( 'TDAC') self.last_good_enable_mask = self.register.get_pixel_register_value( 'Enable') break
def scan(self): with self.readout(): cal_lvl1_command = self.register.get_commands("CAL")[0] + self.register.get_commands("zeros", length=40)[0] + self.register.get_commands("LV1")[0] scan_loop(self, cal_lvl1_command, repeat_command=self.n_injections, use_delay=True, mask_steps=self.mask_steps, enable_mask_steps=None, enable_double_columns=None, same_mask_for_all_dc=True, eol_function=None, digital_injection=True, enable_shift_masks=["Enable", "EnableDigInj"], restore_shift_masks=False, mask=invert_pixel_mask(self.register.get_pixel_register_value('Enable')) if self.use_enable_mask else None)
def scan(self): if self.trig_count == 0: self.consecutive_lvl1 = 2 ** self.register.global_registers['Trig_Count']['bitlength'] else: self.consecutive_lvl1 = self.trig_count enabled_pixels = self.register.get_pixel_register_value('Enable').sum() preselected_pixels = invert_pixel_mask(self.register.get_pixel_register_value('Enable')).sum() disabled_pixels_limit_cnt = int(self.disabled_pixels_limit * self.register.get_pixel_register_value('Enable').sum()) abs_occ_limit = stats.poisson.ppf(0.5, mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1) logging.info('The pixel threshold will be increased when occpancy >%d' % abs_occ_limit) total_occ_limit = int(self.occupancy_limit * self.n_triggers * self.consecutive_lvl1 * enabled_pixels) # Sum of PMF of Poisson distribution (k>0) n_expected_pixel_hits = int((1.0 - stats.poisson.pmf(k=0, mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1)) * enabled_pixels) logging.info('The global threshold will be decreased when total occupancy is <=%d and pixel with hits <=%d' % (total_occ_limit, n_expected_pixel_hits)) max_tdac_steps = max(1, int(np.ceil((1 / self.occupancy_limit) / (self.n_triggers * self.consecutive_lvl1) * (1 / (1 - 0.5))))) tdac_center = 2 ** self.register.pixel_registers['TDAC']['bitlength'] / 2 lvl1_command = self.register.get_commands("LV1")[0] + self.register.get_commands("zeros", length=self.trigger_rate_limit)[0] total_scan_time = int(lvl1_command.length() * 25 * (10 ** -9) * self.n_triggers) self.threshold = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.tdac_step = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.tdac = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.new_tdac = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.enable_mask = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.new_enable_mask = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.occupancy_hist = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) self.occupancy_mask = deque([None] * (self.plot_n_steps + 2), maxlen=self.plot_n_steps + 2) # interpreter = PyDataInterpreter() # histogram = PyDataHistograming() # interpreter.set_trig_count(self.trig_count) # interpreter.set_warning_output(False) # histogram.set_no_scan_parameter() # histogram.create_occupancy_hist(True) coarse_threshold = [self.gdac_range[0]] reached_pixels_limit_cnt = False reached_tdac_center = False reached_gdac_lower_limit = False do_refine_tuning = False for reg_val in coarse_threshold: # outer loop, coarse tuning threshold if self.stop_run.is_set(): break logging.info('Scanning Vthin_AltFine %d', reg_val) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value("Vthin_AltFine", reg_val) commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) # setting FE into RunMode commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) tdac_step = 1 while True: # inner loop if self.stop_run.is_set(): break # histogram.reset() logging.info('TDAC step %d at Vthin_AltFine %d', tdac_step, reg_val) # logging.info('Estimated scan time: %ds', total_scan_time) with self.readout(Vthin_AltFine=reg_val, TDAC_step=tdac_step, fill_buffer=True): got_data = False start = time() self.register_utils.send_command(lvl1_command, repeat=self.n_triggers, wait_for_finish=False, set_length=True, clear_memory=False) while not self.stop_run.wait(0.1): if self.register_utils.is_ready: if got_data: self.progressbar.finish() logging.info('Finished sending %d triggers', self.n_triggers) break if not got_data: if self.data_words_per_second() > 0: got_data = True logging.info('Taking data...') self.progressbar = progressbar.ProgressBar(widgets=['', progressbar.Percentage(), ' ', progressbar.Bar(marker='*', left='|', right='|'), ' ', progressbar.Timer()], maxval=total_scan_time, poll=10, term_width=80).start() else: try: self.progressbar.update(time() - start) except ValueError: pass # use Numpy for analysis and histogramming col_arr, row_arr = convert_data_array(array=self.read_data(), filter_func=is_data_record, converter_func=get_col_row_array_from_data_record_array) occ_hist, _, _ = np.histogram2d(col_arr, row_arr, bins=(80, 336), range=[[1, 80], [1, 336]]) occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) # use FEI4 interpreter for analysis and histogramming # from pybar.daq.readout_utils import data_array_from_data_iterable # raw_data = np.ascontiguousarray(data_array_from_data_iterable(self.read_data()), dtype=np.uint32) # interpreter.interpret_raw_data(raw_data) # interpreter.store_event() # force to create latest event # histogram.add_hits(interpreter.get_hits()) # occ_hist = histogram.get_occupancy()[:, :, 0] # # noisy pixels are set to 1 # occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > abs_occ_limit] = 1 tdac_reg = self.register.get_pixel_register_value('TDAC') decrease_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg > 0) disable_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg == 0) enable_mask = self.register.get_pixel_register_value('Enable') new_enable_mask = np.logical_and(enable_mask, invert_pixel_mask(disable_pixel_mask)) if np.logical_and(occ_mask > 0, enable_mask == 0).sum(): logging.warning('Received data from disabled pixels') # disabled_pixels += disable_pixel_mask.sum() # can lead to wrong values if the enable reg is corrupted disabled_pixels = invert_pixel_mask(new_enable_mask).sum() - preselected_pixels logging.info('Found %d noisy pixels', occ_mask.sum()) logging.info('Increasing threshold of %d pixel(s)', decrease_pixel_mask.sum()) logging.info('Disabling %d pixel(s), total number of disabled pixel(s): %d', disable_pixel_mask.sum(), disabled_pixels) # increasing threshold before writing TDACs to avoid FE becoming noisy self.register.set_global_register_value("Vthin_AltFine", self.gdac_range[0]) commands = [] commands.extend(self.register.get_commands("ConfMode")) commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) self.register_utils.send_commands(commands) # writing TDAC new_tdac_reg = tdac_reg.copy() new_tdac_reg[decrease_pixel_mask] -= 1 # smaller TDAC translates to higher threshold self.register.set_pixel_register_value('TDAC', new_tdac_reg) self.register.set_pixel_register_value('Enable', new_enable_mask) commands = [] commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='TDAC')) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) self.register_utils.send_commands(commands) # writing threshold value after writing TDACs self.register.set_global_register_value("Vthin_AltFine", reg_val) commands = [] commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) if (not do_refine_tuning and occ_hist.sum() <= total_occ_limit and occ_mask.sum() <= n_expected_pixel_hits) or (tdac_step >= max_tdac_steps): logging.info('Stop tuning TDACs at Vthin_AltFine %d', reg_val) self.threshold.appendleft(self.register.get_global_register_value("Vthin_AltFine")) self.tdac_step.appendleft(tdac_step) self.tdac.appendleft(tdac_reg) self.new_tdac.appendleft(new_tdac_reg) self.enable_mask.appendleft(enable_mask) self.new_enable_mask.appendleft(new_enable_mask) self.occupancy_hist.appendleft(occ_hist.copy()) self.occupancy_mask.appendleft(occ_mask.copy()) if not do_refine_tuning and np.mean(new_tdac_reg[new_enable_mask]) <= tdac_center + (1 if self.refine_tuning else 0): reached_tdac_center = True if not do_refine_tuning and disabled_pixels > disabled_pixels_limit_cnt: reached_pixels_limit_cnt = True logging.info('Limit of disabled pixels reached: %d (limit %d).' % (disabled_pixels, disabled_pixels_limit_cnt)) if not do_refine_tuning and reg_val <= self.gdac_range[1]: reached_gdac_lower_limit = True break else: logging.info('Continue tuning TDACs at Vthin_AltFine %d', reg_val) # increase scan parameter counter tdac_step += 1 if not self.refine_tuning and (reached_pixels_limit_cnt or reached_tdac_center or reached_gdac_lower_limit): pass # will exit loop elif do_refine_tuning: logging.info("Finished TDAC refine tuning.") elif reached_pixels_limit_cnt or reached_tdac_center or reached_gdac_lower_limit: do_refine_tuning = True logging.info("Starting TDAC refine tuning...") coarse_threshold.append(reg_val - 1) abs_occ_limit = stats.poisson.ppf(0.99, mu=self.occupancy_limit * self.n_triggers * self.consecutive_lvl1) logging.info('The pixel threshold will be increased when occpancy >%d' % abs_occ_limit) max_tdac_steps = max(1, int(np.ceil((1 / self.occupancy_limit) / (self.n_triggers * self.consecutive_lvl1) * (1 / (1 - 0.99))))) else: coarse_threshold.append(reg_val - 1)
def scan(self): scan_parameter_range = [self.register.get_global_register_value("Vthin_AltFine"), 0] if self.scan_parameters.Vthin_AltFine[0]: scan_parameter_range[0] = self.scan_parameters.Vthin_AltFine[0] if self.scan_parameters.Vthin_AltFine[1]: scan_parameter_range[1] = self.scan_parameters.Vthin_AltFine[1] steps = 1 if self.scan_parameters.Step: steps = self.scan_parameters.Step lvl1_command = self.register.get_commands("LV1")[0] + self.register.get_commands("zeros", length=self.trigger_rate_limit)[0] self.total_scan_time = int(lvl1_command.length() * 25 * (10 ** -9) * self.n_triggers) disabled_pixels_limit_cnt = int(self.disabled_pixels_limit * 336 * 80) preselected_pixels = invert_pixel_mask(self.register.get_pixel_register_value('Enable')).sum() disabled_pixels = 0 for reg_val in range(scan_parameter_range[0], scan_parameter_range[1] - 1, -1): if self.stop_run.is_set(): break self.register.create_restore_point(name=str(reg_val)) logging.info('Scanning Vthin_AltFine %d', reg_val) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value("Vthin_AltFine", reg_val) # set number of consecutive triggers commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) # setting FE into RunMode commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) step = 0 while True: if self.stop_run.is_set(): break self.histograming.reset() step += 1 logging.info('Step %d / %d at Vthin_AltFine %d', step, steps, reg_val) logging.info('Estimated scan time: %ds', self.total_scan_time) with self.readout(Vthin_AltFine=reg_val, Step=step, reset_sram_fifo=True, fill_buffer=True, clear_buffer=True, callback=self.handle_data): got_data = False start = time() self.register_utils.send_command(lvl1_command, repeat=self.n_triggers, wait_for_finish=False, set_length=True, clear_memory=False) while not self.stop_run.wait(0.1): if self.register_utils.is_ready: if got_data: self.progressbar.finish() logging.info('Finished sending %d triggers', self.n_triggers) break if not got_data: if self.fifo_readout.data_words_per_second() > 0: got_data = True logging.info('Taking data...') self.progressbar = progressbar.ProgressBar(widgets=['', progressbar.Percentage(), ' ', progressbar.Bar(marker='*', left='|', right='|'), ' ', progressbar.Timer()], maxval=self.total_scan_time, poll=10, term_width=80).start() else: try: self.progressbar.update(time() - start) except ValueError: pass # Use fast C++ hit histograming to save time raw_data = np.ascontiguousarray(data_array_from_data_iterable(self.fifo_readout.data), dtype=np.uint32) self.interpreter.interpret_raw_data(raw_data) self.interpreter.store_event() # force to create latest event self.histograming.add_hits(self.interpreter.get_hits()) occ_hist = self.histograming.get_occupancy()[:, :, 0] # noisy pixels are set to 1 occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > self.occupancy_limit * self.n_triggers * self.consecutive_lvl1] = 1 tdac_reg = self.register.get_pixel_register_value('TDAC') decrease_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg > 0) disable_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg == 0) enable_reg = self.register.get_pixel_register_value('Enable') enable_mask = np.logical_and(enable_reg, invert_pixel_mask(disable_pixel_mask)) if np.logical_and(occ_mask > 0, enable_reg == 0).sum(): logging.warning('Received data from disabled pixels') # disabled_pixels += disable_pixel_mask.sum() # can lead to wrong values if the enable reg is corrupted disabled_pixels = invert_pixel_mask(enable_mask).sum() - preselected_pixels if disabled_pixels > disabled_pixels_limit_cnt: logging.info('Limit of disabled pixels reached: %d (limit %d)... stopping scan' % (disabled_pixels, disabled_pixels_limit_cnt)) self.register.restore(name=str(reg_val)) break else: logging.info('Increasing threshold of %d pixel(s)', decrease_pixel_mask.sum()) logging.info('Disabling %d pixel(s), total number of disabled pixel(s): %d', disable_pixel_mask.sum(), disabled_pixels) tdac_reg[decrease_pixel_mask] -= 1 self.register.set_pixel_register_value('TDAC', tdac_reg) self.register.set_pixel_register_value('Enable', enable_mask) commands = [] commands.extend(self.register.get_commands("ConfMode")) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='TDAC')) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) if occ_mask.sum() == 0 or step == steps or decrease_pixel_mask.sum() < disabled_pixels_limit_cnt: self.register.clear_restore_points(name=str(reg_val)) self.last_tdac_distribution = self.register.get_pixel_register_value('TDAC') self.last_occupancy_hist = occ_hist.copy() self.last_occupancy_mask = occ_mask.copy() self.last_reg_val = reg_val self.last_step = step break else: logging.info('Found %d noisy pixels... repeat tuning step for Vthin_AltFine %d', occ_mask.sum(), reg_val) if disabled_pixels > disabled_pixels_limit_cnt: self.last_good_threshold = self.register.get_global_register_value("Vthin_AltFine") self.last_good_tdac = self.register.get_pixel_register_value('TDAC') self.last_good_enable_mask = self.register.get_pixel_register_value('Enable') break
def scan(self): scan_parameter_range = [self.register.get_global_register_value("Vthin_AltFine"), 0] if self.scan_parameters.Vthin_AltFine[0]: scan_parameter_range[0] = self.scan_parameters.Vthin_AltFine[0] if self.scan_parameters.Vthin_AltFine[1]: scan_parameter_range[1] = self.scan_parameters.Vthin_AltFine[1] steps = 1 if self.scan_parameters.Step: steps = self.scan_parameters.Step lvl1_command = self.register.get_commands("LV1")[0] + self.register.get_commands("zeros", length=self.trigger_rate_limit)[0] self.total_scan_time = int(lvl1_command.length() * 25 * (10 ** -9) * self.n_triggers) preselected_pixels = invert_pixel_mask(self.register.get_pixel_register_value('Enable')).sum() disabled_pixels_limit_cnt = int(self.disabled_pixels_limit * self.register.get_pixel_register_value('Enable').sum()) disabled_pixels = 0 self.last_reg_val = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_step = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_good_threshold = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_good_tdac = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_good_enable_mask = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_occupancy_hist = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) self.last_occupancy_mask = deque([None] * self.increase_threshold, maxlen=self.increase_threshold + 1) for reg_val in range(scan_parameter_range[0], scan_parameter_range[1] - 1, -1): if self.stop_run.is_set(): break logging.info('Scanning Vthin_AltFine %d', reg_val) commands = [] commands.extend(self.register.get_commands("ConfMode")) self.register.set_global_register_value("Vthin_AltFine", reg_val) # set number of consecutive triggers commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"])) # setting FE into RunMode commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) step = 0 while True: if self.stop_run.is_set(): break self.histogram.reset() step += 1 logging.info('Step %d / %d at Vthin_AltFine %d', step, steps, reg_val) logging.info('Estimated scan time: %ds', self.total_scan_time) with self.readout(Vthin_AltFine=reg_val, Step=step, reset_sram_fifo=True, fill_buffer=True, clear_buffer=True, callback=self.handle_data): got_data = False start = time() self.register_utils.send_command(lvl1_command, repeat=self.n_triggers, wait_for_finish=False, set_length=True, clear_memory=False) while not self.stop_run.wait(0.1): if self.register_utils.is_ready: if got_data: self.progressbar.finish() logging.info('Finished sending %d triggers', self.n_triggers) break if not got_data: if self.fifo_readout.data_words_per_second() > 0: got_data = True logging.info('Taking data...') self.progressbar = progressbar.ProgressBar(widgets=['', progressbar.Percentage(), ' ', progressbar.Bar(marker='*', left='|', right='|'), ' ', progressbar.Timer()], maxval=self.total_scan_time, poll=10, term_width=80).start() else: try: self.progressbar.update(time() - start) except ValueError: pass # Use fast C++ hit histogramming to save time raw_data = np.ascontiguousarray(data_array_from_data_iterable(self.fifo_readout.data), dtype=np.uint32) self.interpreter.interpret_raw_data(raw_data) self.interpreter.store_event() # force to create latest event self.histogram.add_hits(self.interpreter.get_hits()) occ_hist = self.histogram.get_occupancy()[:, :, 0] # noisy pixels are set to 1 occ_mask = np.zeros(shape=occ_hist.shape, dtype=np.dtype('>u1')) occ_mask[occ_hist > self.abs_occ_limit] = 1 tdac_reg = self.register.get_pixel_register_value('TDAC') decrease_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg > 0) disable_pixel_mask = np.logical_and(occ_mask > 0, tdac_reg == 0) enable_reg = self.register.get_pixel_register_value('Enable') enable_mask = np.logical_and(enable_reg, invert_pixel_mask(disable_pixel_mask)) if np.logical_and(occ_mask > 0, enable_reg == 0).sum(): logging.warning('Received data from disabled pixels') # disabled_pixels += disable_pixel_mask.sum() # can lead to wrong values if the enable reg is corrupted disabled_pixels = invert_pixel_mask(enable_mask).sum() - preselected_pixels if disabled_pixels > disabled_pixels_limit_cnt: logging.info('Limit of disabled pixels reached: %d (limit %d)... stopping scan' % (disabled_pixels, disabled_pixels_limit_cnt)) break else: logging.info('Increasing threshold of %d pixel(s)', decrease_pixel_mask.sum()) logging.info('Disabling %d pixel(s), total number of disabled pixel(s): %d', disable_pixel_mask.sum(), disabled_pixels) tdac_reg[decrease_pixel_mask] -= 1 self.register.set_pixel_register_value('TDAC', tdac_reg) self.register.set_pixel_register_value('Enable', enable_mask) commands = [] commands.extend(self.register.get_commands("ConfMode")) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='TDAC')) commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name='Enable')) commands.extend(self.register.get_commands("RunMode")) self.register_utils.send_commands(commands) if occ_mask.sum() == 0 or step == steps or decrease_pixel_mask.sum() < disabled_pixels_limit_cnt: self.last_reg_val.appendleft(reg_val) self.last_step.appendleft(step) self.last_good_threshold.appendleft(self.register.get_global_register_value("Vthin_AltFine")) self.last_good_tdac.appendleft(self.register.get_pixel_register_value("TDAC")) self.last_good_enable_mask.appendleft(self.register.get_pixel_register_value("Enable")) self.last_occupancy_hist.appendleft(occ_hist.copy()) self.last_occupancy_mask.appendleft(occ_mask.copy()) break else: logging.info('Found %d noisy pixels... repeat tuning step for Vthin_AltFine %d', occ_mask.sum(), reg_val) if disabled_pixels > disabled_pixels_limit_cnt or scan_parameter_range[1] == reg_val: break