Example #1
0
 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)
Example #4
0
    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,
                    )
Example #5
0
    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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
    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)
Example #15
0
    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)
Example #16
0
    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)
Example #17
0
 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)
Example #18
0
    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)
Example #19
0
    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)
Example #20
0
    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")
Example #21
0
    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)
Example #22
0
    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)
Example #23
0
    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)
Example #24
0
    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)
Example #25
0
    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
Example #27
0
 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)
Example #28
0
    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