Beispiel #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 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)
Beispiel #3
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)
    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 <= 0:
            logging.info('Any noise hit will lead to an increased pixel threshold.')
        else:
            logging.info('The pixel threshold of any pixel with an occpancy >%d will be increased' % self.abs_occ_limit)
            

        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # TDAC
        tdac_max = 2 ** self.register.pixel_registers['TDAC']['bitlength'] - 1
        self.register.set_pixel_register_value("TDAC", tdac_max)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="TDAC"))
        mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span)
        # Enable
        if self.use_enable_mask:
            self.register.set_pixel_register_value("Enable", np.logical_and(mask, self.register.get_pixel_register_value("Enable")))
        else:
            self.register.set_pixel_register_value("Enable", mask)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="Enable"))
        # Imon
        self.register.set_pixel_register_value('Imon', 1)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, 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)

        self.interpreter = PyDataInterpreter()
        self.histograming = PyDataHistograming()
        self.interpreter.set_trig_count(self.trig_count)
        self.interpreter.set_warning_output(False)
        self.histograming.set_no_scan_parameter()
        self.histograming.create_occupancy_hist(True)
    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 <= 0:
            logging.info('Any noise hit will lead to an increased pixel threshold.')
        else:
            logging.info('The pixel threshold of any pixel with an occpancy >%d will be increased' % self.abs_occ_limit)
            

        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # TDAC
        tdac_max = 2 ** self.register.pixel_registers['TDAC']['bitlength'] - 1
        self.register.set_pixel_register_value("TDAC", tdac_max)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="TDAC"))
        mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span)
        # Enable
        if self.use_enable_mask:
            self.register.set_pixel_register_value("Enable", np.logical_and(mask, self.register.get_pixel_register_value("Enable")))
        else:
            self.register.set_pixel_register_value("Enable", mask)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="Enable"))
        # Imon
        self.register.set_pixel_register_value('Imon', 1)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, 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)

        self.interpreter = PyDataInterpreter()
        self.histogram = PyDataHistograming()
        self.interpreter.set_trig_count(self.trig_count)
        self.interpreter.set_warning_output(False)
        self.histogram.set_no_scan_parameter()
        self.histogram.create_occupancy_hist(True)
Beispiel #6
0
    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # GDAC
        self.gdac_range = [self.register.get_global_register_value("Vthin_AltFine"), 0]  # default GDAC range
        if self.start_gdac is not None:
            self.gdac_range[0] = min(self.start_gdac, 2 ** self.register.global_registers['Vthin_AltFine']['bitlength'])
        if self.gdac_lower_limit is not None:
            self.gdac_range[1] = max(self.gdac_lower_limit, 0)
        self.register.set_global_register_value("Vthin_AltFine", self.gdac_range[0])  # set to start threshold value
        commands.extend(self.register.get_commands("WrRegister", name=["Vthin_AltFine"]))
        # TDAC
        tdac_max = 2 ** self.register.pixel_registers['TDAC']['bitlength'] - 1
        self.register.set_pixel_register_value("TDAC", tdac_max)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="TDAC"))
        mask = make_box_pixel_mask_from_col_row(column=self.col_span, row=self.row_span)
        # Enable
        if self.use_enable_mask:
            self.register.set_pixel_register_value("Enable", np.logical_and(mask, self.register.get_pixel_register_value("Enable")))
        else:
            self.register.set_pixel_register_value("Enable", mask)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=False, name="Enable"))
        # Imon
        self.register.set_pixel_register_value('Imon', 1)
        commands.extend(self.register.get_commands("WrFrontEnd", same_mask_for_all_dc=True, 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)
Beispiel #7
0
class IleakScan(Fei4RunBase):
    '''Pixel leakage current scan using external multimeter.
    '''
    _default_run_conf = {
        "broadcast_commands":
        False,
        "threaded_scan":
        False,
        "pixels":
        (np.dstack(
            np.where(make_box_pixel_mask_from_col_row([1, 16], [1, 36]) == 1))
         + 1).tolist()[0],  # list of (col, row) tupels. From 1 to 80/336.
    }

    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        self.register.set_pixel_register_value('Imon', 0)
        commands.extend(
            self.register.get_commands("WrFrontEnd",
                                       same_mask_for_all_dc=True,
                                       name='Imon'))
        self.register_utils.send_commands(commands)
        self.ileakmap = np.zeros(shape=(80, 336))

    def scan(self):
        logging.info("Scanning %d pixels" % len(self.pixels))
        progress_bar = progressbar.ProgressBar(widgets=[
            '',
            progressbar.Percentage(), ' ',
            progressbar.Bar(marker='*', left='|', right='|'), ' ',
            progressbar.AdaptiveETA()
        ],
                                               maxval=len(self.pixels),
                                               term_width=80)
        progress_bar.start()

        data_out = self.raw_data_file.h5_file.create_carray(
            self.raw_data_file.h5_file.root,
            name='Ileak_map',
            title='Leakage current per pixel in arbitrary units',
            atom=tb.Atom.from_dtype(self.ileakmap.dtype),
            shape=self.ileakmap.shape,
            filters=tb.Filters(complib='blosc', complevel=5, fletcher32=False))

        for pixel_index, (column, row) in enumerate(self.pixels):
            if self.stop_run.is_set():
                break
            # Set Imon for actual pixel and configure FE
            mask = np.zeros(shape=(80, 336))
            mask[column - 1, row - 1] = 1
            commands = []
            commands.extend(self.register.get_commands("ConfMode"))
            self.register.set_pixel_register_value('Imon', mask)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           name='Imon'))
            self.register_utils.send_commands(commands)
            # Read and store voltage
            voltage_string = self.dut['Multimeter'].get_voltage()
            voltage = float(voltage_string.split(',')[0][:-4])
            self.ileakmap[column - 1, row - 1] = voltage

            progress_bar.update(pixel_index)

        progress_bar.finish()

        data_out[:] = self.ileakmap

    def analyze(self):
        with tb.open_file(self.output_filename + '.h5', 'r') as in_file_h5:
            data = in_file_h5.root.Ileak_map[:]
            data = np.ma.masked_where(data == 0, data)
            plot_three_way(hist=data.transpose(),
                           title="Ileak",
                           x_axis_title="Ileak",
                           filename=self.output_filename +
                           '.pdf')  # , minimum=0, maximum=np.amax(data))
    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
        if self.occupancy_limit * self.n_triggers * self.consecutive_lvl1 < 1.0:
            logging.warning(
                'Number of triggers too low for given occupancy limit. Any noise hit will lead to a masked pixel.'
            )

        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        # TDAC
        tdac_max = 2**self.register.pixel_registers['TDAC']['bitlength'] - 1
        self.register.set_pixel_register_value("TDAC", tdac_max)
        commands.extend(
            self.register.get_commands("WrFrontEnd",
                                       same_mask_for_all_dc=False,
                                       name="TDAC"))
        mask = make_box_pixel_mask_from_col_row(column=self.col_span,
                                                row=self.row_span)
        # Enable
        if self.use_enable_mask:
            self.register.set_pixel_register_value(
                "Enable",
                np.logical_and(
                    mask, self.register.get_pixel_register_value("Enable")))
        else:
            self.register.set_pixel_register_value("Enable", mask)
        commands.extend(
            self.register.get_commands("WrFrontEnd",
                                       same_mask_for_all_dc=False,
                                       name="Enable"))
        # Imon
        self.register.set_pixel_register_value('Imon', 1)
        commands.extend(
            self.register.get_commands("WrFrontEnd",
                                       same_mask_for_all_dc=True,
                                       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)
Beispiel #9
0
class HitOrCalibration(Fei4RunBase):
    ''' Hit Or calibration scan
    '''
    _default_run_conf = {
        "repeat_command":
        200,
        "injection_delay":
        5000,  # for really low feedbacks (ToT >> 300 ns) one needs to increase the injection delay
        "scan_parameters":
        [('column', None), ('row', None),
         ('PlsrDAC',
          [40, 50, 60, 80, 130, 180, 230, 280, 340, 440, 540, 640,
           740])],  # 0 400 sufficient
        "reset_rx_on_error":
        True,
        "plot_tdc_histograms":
        False,
        "pixels": (np.dstack(
            np.where(
                make_box_pixel_mask_from_col_row([40, 41], [150, 151]) == 1)) +
                   1).tolist()
        [0],  # list of (col, row) tupels. From 1 to 80/336.
        "enable_masks": ["Enable", "C_Low", "C_High"],
        "disable_masks": ["Imon"]
    }

    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        self.register.set_global_register_value(
            "Trig_Count", 6)  # decrease trigger count to reduce data
        self.register.set_global_register_value(
            "Trig_Lat", 215)  # adjust delay for smaller bcid window
        self.register.set_global_register_value(
            "ErrorMask", 1536)  # deactivate hit bus service record
        commands.extend(
            self.register.get_commands(
                "WrRegister", name=["Trig_Lat", "Trig_Count", "ErrorMask"]))
        self.register_utils.send_commands(commands)

    def scan(self):
        def write_double_column(column):
            return (column - 1) / 2

        def inject_double_column(column):
            if column == 80:
                return 39
            else:
                return (column) / 2

        cal_lvl1_command = self.register.get_commands(
            "CAL")[0] + self.register.get_commands(
                "zeros", length=40)[0] + self.register.get_commands(
                    "LV1")[0] + self.register.get_commands(
                        "zeros", length=self.injection_delay)[0]
        scan_par_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 %d pixels" % len(self.pixels))
        for pixel_index, pixel in enumerate(self.pixels):
            if self.stop_run.is_set():
                break

            column = pixel[0]
            row = pixel[1]
            logging.info('Scanning pixel: %d / %d (column / row)', column, row)
            if pixel_index:
                dcs = [write_double_column(column)]
                dcs.append(write_double_column(self.pixels[pixel_index -
                                                           1][0]))
            else:
                dcs = []
            commands = []
            commands.extend(self.register.get_commands("ConfMode"))
            single_pixel_enable_mask = make_pixel_mask_from_col_row([column],
                                                                    [row])
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_enable_mask), self.enable_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.enable_masks,
                                           joint_write=True))
            single_pixel_disable_mask = make_pixel_mask_from_col_row([column],
                                                                     [row],
                                                                     default=1,
                                                                     value=0)
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_disable_mask), self.disable_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.disable_masks,
                                           joint_write=True))
            self.register.set_global_register_value(
                "Colpr_Addr", inject_double_column(column))
            commands.append(
                self.register.get_commands("WrRegister",
                                           name=["Colpr_Addr"])[0])
            self.register_utils.send_commands(commands)
            # self.fifo_readout.reset_sram_fifo()  # after mask shifting you have AR VR in SRAM that are not of interest but reset takes a long time, so ignore the warning

            self.dut['TDC']['ENABLE'] = True
            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_par_name, scan_parameter_value)
                commands.extend(
                    self.register.get_commands("WrRegister",
                                               name=[scan_par_name]))
                commands.extend(self.register.get_commands("RunMode"))
                self.register_utils.send_commands(commands)

                self.dut['TDC']['EN_ARMING'] = True
                with self.readout(column=column,
                                  row=row,
                                  **{scan_par_name: scan_parameter_value}):
                    self.register_utils.send_command(
                        command=cal_lvl1_command, repeat=self.repeat_command)

                self.dut['TDC']['EN_ARMING'] = False
            self.dut['TDC']['ENABLE'] = False

    def handle_data(self, data):
        self.raw_data_file.append_item(
            data,
            scan_parameters=self.scan_parameters._asdict(),
            new_file=['column'],
            flush=False)  # Create new file for each scan parameter change

    def analyze(self):
        create_hitor_calibration(self.output_filename)
Beispiel #10
0
if __name__ == "__main__":
    # Settings
    bias_voltage = -80
    max_iv_voltage = -100
    #   Tuning
    cref = 12
    target_threshold = 34
    target_charge = 300
    target_tot = 9

    #   TDC measurements
    plsr_dacs = [target_threshold, 40, 50, 60, 80, 100, 120, 150, 200, 250, 300, 350, 400, 500, 600, 700, 800]  # PlsrDAC range for TDC calibration, should start at threshold
    col_span = [55, 75]#[50, 78]  # pixel column range to use in TDC scans
    row_span = [125, 225]#[20, 315]  # pixel row range to use in TDC scans
    tdc_pixel = make_box_pixel_mask_from_col_row(column=[col_span[0], col_span[1]], row=[row_span[0], row_span[1]])  # edge pixel are not used in analysis

    runmngr = RunManager('configuration.yaml')

    # IV scan
    runmngr.run_run(run=IVScan, run_conf={"voltages": np.arange(-1, max_iv_voltage - 1, -1), "max_voltage": max_iv_voltage, "bias_voltage": bias_voltage, "minimum_delay": 0.5})

    # FE check and complete tuning
    runmngr.run_run(run=RegisterTest) 
    runmngr.run_run(run=DigitalScan)  # digital scan with std. settings

    if runmngr.current_run.register.flavor == 'fei4a':  # FEI4 A related config changes, Deactivate noisy edge columns if FE-I4A
        runmngr.current_run.register.set_global_register_value("DisableColumnCnfg", 549755813891)  # Disable noisy columns
        runmngr.current_run.register.set_global_register_value("Cref", cref)  # Set correct cref
        runmngr.current_run.register.save_configuration(runmngr.current_run.register.configuration_file)
        runmngr.run_run(run=DigitalScan)  # repeat digital scan with specific settings
Beispiel #11
0
class HitOrCalibration(Fei4RunBase):
    ''' Hit Or calibration scan
    '''
    _default_run_conf = {
        "repeat_command":
        1000,
        "scan_parameters":
        [('column', None), ('row', None),
         ('PlsrDAC', [
             i for j in (range(26, 70, 10), range(80, 200, 50),
                         range(240, 400, 100)) for i in j
         ])],  # 0 400 sufficient
        "plot_tdc_histograms":
        False,
        "pixels": (np.dstack(
            np.where(
                make_box_pixel_mask_from_col_row([40, 45], [150, 155]) == 1)) +
                   1)[0],  # list of (col, row) tupels. From 1 to 80/336.
        "enable_masks": ["Enable", "C_Low", "C_High"],
        "disable_masks": ["Imon"]
    }

    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        self.register.set_global_register_value(
            "Trig_Count", 5)  # decrease trigger count to reduce data
        self.register.set_global_register_value(
            "Trig_Lat", 216)  # adjust delay for smaller bcid window
        self.register.set_global_register_value(
            "ErrorMask", 1536)  # deactivate hit bus service record
        commands.extend(
            self.register.get_commands(
                "WrRegister", name=["Trig_Lat", "Trig_Count", "ErrorMask"]))
        self.register_utils.send_commands(commands)

    def scan(self):
        def write_double_column(column):
            return (column - 1) / 2

        def inject_double_column(column):
            if column == 80:
                return 39
            else:
                return (column) / 2

        cal_lvl1_command = self.register.get_commands(
            "CAL")[0] + self.register.get_commands(
                "zeros", length=40)[0] + self.register.get_commands(
                    "LV1")[0] + self.register.get_commands("zeros",
                                                           length=250)[0]
        scan_par_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

        for pixel_index, pixel in enumerate(self.pixels):
            column = pixel[0]
            row = pixel[1]
            logging.info('Scanning pixel: %d / %d (column / row)' %
                         (column, row))
            if pixel_index:
                dcs = [write_double_column(column)]
                dcs.append(write_double_column(self.pixels[pixel_index -
                                                           1][0]))
            else:
                dcs = []
            commands = []
            commands.extend(self.register.get_commands("ConfMode"))
            single_pixel_enable_mask = make_pixel_mask_from_col_row([column],
                                                                    [row])
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_enable_mask), self.enable_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.enable_masks,
                                           joint_write=True))
            single_pixel_disable_mask = make_pixel_mask_from_col_row([column],
                                                                     [row],
                                                                     default=1,
                                                                     value=0)
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_disable_mask), self.disable_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.disable_masks,
                                           joint_write=True))
            self.register.set_global_register_value(
                "Colpr_Addr", inject_double_column(column))
            commands.append(
                self.register.get_commands("WrRegister",
                                           name=["Colpr_Addr"])[0])
            self.register_utils.send_commands(commands)
            #             self.fifo_readout.reset_sram_fifo()  # after mask shifting you have AR VR in Sram that are not of interest but reset takes a long time

            self.dut['tdc_rx2']['ENABLE'] = True
            for scan_parameter_value in scan_parameters_values:
                if self.stop_run.is_set():
                    break
                logging.info('Scan step: %s %d' %
                             (scan_par_name, scan_parameter_value))

                commands = []
                commands.extend(self.register.get_commands("ConfMode"))
                self.register.set_global_register_value(
                    scan_par_name, scan_parameter_value)
                commands.extend(
                    self.register.get_commands("WrRegister",
                                               name=[scan_par_name]))
                commands.extend(self.register.get_commands("RunMode"))
                self.register_utils.send_commands(commands)

                self.dut['tdc_rx2']['EN_ARMING'] = True
                with self.readout(column=column,
                                  row=row,
                                  PlsrDAC=scan_parameter_value):
                    self.register_utils.send_command(
                        command=cal_lvl1_command, repeat=self.repeat_command)

                self.dut['tdc_rx2']['EN_ARMING'] = False
            self.dut['tdc_rx2']['ENABLE'] = False

    def analyze(self):
        logging.info('Analyze and plot results')

        def plot_calibration(col_row_combinations, scan_parameter,
                             calibration_data, repeat_command,
                             filename):  # Result calibration plot function
            for index, (column, row) in enumerate(col_row_combinations):
                logging.info("Plot calibration for pixel " + str(column) +
                             '/' + str(row))
                fig = Figure()
                canvas = FigureCanvas(fig)
                ax = fig.add_subplot(111)
                fig.patch.set_facecolor('white')
                ax.grid(True)
                ax.errorbar(
                    scan_parameter,
                    calibration_data[column - 1, row - 1, :, 0] * 25. + 25.,
                    yerr=[
                        calibration_data[column - 1, row - 1, :, 2] * 25,
                        calibration_data[column - 1, row - 1, :, 2] * 25
                    ],
                    fmt='o',
                    label='FE-I4 ToT [ns]')
                ax.errorbar(
                    scan_parameter,
                    calibration_data[column - 1, row - 1, :, 1] * 1.5625,
                    yerr=[
                        calibration_data[column - 1, row - 1, :, 3] * 1.5625,
                        calibration_data[column - 1, row - 1, :, 3] * 1.5625
                    ],
                    fmt='o',
                    label='TDC ToT [ns]')
                ax.set_title('Calibration for pixel ' + str(column) + '/' +
                             str(row) + '; ' + str(repeat_command) +
                             ' injections per setting')
                ax.set_xlabel('Charge [PlsrDAC]')
                ax.set_ylabel('TOT')
                ax.legend(loc=0)
                filename.savefig(fig)
                if index > 100:  # stop for too many plots
                    break

        with AnalyzeRawData(
                raw_data_file=self.output_filename, create_pdf=True
        ) as analyze_raw_data:  # Interpret the raw data file
            analyze_raw_data.create_occupancy_hist = False  # too many scan parameters to do in ram histograming
            analyze_raw_data.create_hit_table = True
            analyze_raw_data.create_tdc_hist = True
            analyze_raw_data.interpreter.use_tdc_word(
                True
            )  # align events at TDC words, first word of event has to be a tdc word
            analyze_raw_data.interpret_word_table()
            analyze_raw_data.interpreter.print_summary()
            analyze_raw_data.plot_histograms()

        with tb.open_file(
                self.output_filename + '_interpreted.h5', 'r'
        ) as in_file_h5:  # Get scan parameters from interpreted file
            scan_parameters_dict = get_scan_parameter(
                in_file_h5.root.meta_data[:])
            inner_loop_parameter_values = scan_parameters_dict[next(
                reversed(scan_parameters_dict)
            )]  # inner loop parameter name is unknown
            scan_parameter_names = scan_parameters_dict.keys()
            n_par_combinations = len(
                get_unique_scan_parameter_combinations(
                    in_file_h5.root.meta_data[:]))
            col_row_combinations = get_unique_scan_parameter_combinations(
                in_file_h5.root.meta_data[:],
                scan_parameters=('column', 'row'),
                scan_parameter_columns_only=True)

        with tb.openFile(self.output_filename + "_calibration.h5",
                         mode="w") as calibration_data_file:
            logging.info('Create calibration')
            output_pdf = PdfPages(self.output_filename + "_calibration.pdf")
            calibration_data = np.zeros(
                shape=(80, 336, len(inner_loop_parameter_values), 4),
                dtype='f4'
            )  # result of the calibration is a histogram with col_index, row_index, plsrDAC value, mean discrete tot, rms discrete tot, mean tot from TDC, rms tot from TDC

            progress_bar = progressbar.ProgressBar(widgets=[
                '',
                progressbar.Percentage(), ' ',
                progressbar.Bar(marker='*', left='|', right='|'), ' ',
                progressbar.AdaptiveETA()
            ],
                                                   maxval=n_par_combinations,
                                                   term_width=80)
            old_scan_parameters = None
            tot_data = None
            tdc_data = None

            for index, (actual_scan_parameters, hits) in enumerate(
                    get_hits_of_scan_parameter(self.output_filename +
                                               '_interpreted.h5',
                                               scan_parameter_names,
                                               chunk_size=1.5e7)):
                if index == 0:
                    progress_bar.start(
                    )  # start after the event index is created to get reasonable ETA

                actual_col, actual_row, _ = actual_scan_parameters

                if len(hits[np.logical_and(hits['column'] != actual_col,
                                           hits['row'] != actual_row)]):
                    logging.warning(
                        'There are %d hits from not selected pixels in the data'
                        % len(hits[np.logical_and(hits['column'] != actual_col,
                                                  hits['row'] != actual_row)]))

                hits = hits[
                    (hits['event_status'] & 0b0000011110001000) ==
                    0b0000000100000000]  # only take hits from good events (one TDC word only, no error)
                column, row, tot, tdc = hits['column'], hits['row'], hits[
                    'tot'], hits['TDC']

                if old_scan_parameters != actual_scan_parameters:  # Store the data of the actual PlsrDAC value
                    if old_scan_parameters:  # Special case for the first PlsrDAC setting
                        inner_loop_scan_parameter_index = np.where(
                            old_scan_parameters[-1] ==
                            inner_loop_parameter_values
                        )[0][
                            0]  # translate the scan parameter value to an index for the result histogram
                        calibration_data[column - 1, row - 1,
                                         inner_loop_scan_parameter_index,
                                         0] = np.mean(tot_data)
                        calibration_data[column - 1, row - 1,
                                         inner_loop_scan_parameter_index,
                                         1] = np.mean(tdc_data)
                        calibration_data[column - 1, row - 1,
                                         inner_loop_scan_parameter_index,
                                         2] = np.std(tot_data)
                        calibration_data[column - 1, row - 1,
                                         inner_loop_scan_parameter_index,
                                         3] = np.std(tdc_data)
                        progress_bar.update(index)
                    tot_data = np.array(tot)
                    tdc_data = np.array(tdc)
                    old_scan_parameters = actual_scan_parameters
                else:
                    np.concatenate((tot_data, tot))
                    np.concatenate((tdc_data, tdc))

            else:
                inner_loop_scan_parameter_index = np.where(
                    old_scan_parameters[-1] == inner_loop_parameter_values
                )[0][
                    0]  # translate the scan parameter value to an index for the result histogram
                calibration_data[column - 1, row - 1,
                                 inner_loop_scan_parameter_index,
                                 0] = np.mean(tot_data)
                calibration_data[column - 1, row - 1,
                                 inner_loop_scan_parameter_index,
                                 1] = np.mean(tdc_data)
                calibration_data[column - 1, row - 1,
                                 inner_loop_scan_parameter_index,
                                 2] = np.std(tot_data)
                calibration_data[column - 1, row - 1,
                                 inner_loop_scan_parameter_index,
                                 3] = np.std(tdc_data)

            calibration_data_out = calibration_data_file.createCArray(
                calibration_data_file.root,
                name='HitOrCalibration',
                title='Hit OR calibration data',
                atom=tb.Atom.from_dtype(calibration_data.dtype),
                shape=calibration_data.shape,
                filters=tb.Filters(complib='blosc',
                                   complevel=5,
                                   fletcher32=False))
            calibration_data_out[:] = calibration_data
            calibration_data_out.attrs.dimensions = scan_parameter_names
            calibration_data_out.attrs.scan_parameter_values = inner_loop_parameter_values
            plot_calibration(col_row_combinations,
                             scan_parameter=inner_loop_parameter_values,
                             calibration_data=calibration_data,
                             repeat_command=self.repeat_command,
                             filename=output_pdf)
            output_pdf.close()
            progress_bar.finish()
Beispiel #12
0
    max_iv_voltage = -100
    #   Tuning
    cref = 12
    target_threshold = 34
    target_charge = 300
    target_tot = 9

    #   TDC measurements
    plsr_dacs = [
        target_threshold, 40, 50, 60, 80, 100, 120, 150, 200, 250, 300, 350,
        400, 500, 600, 700, 800
    ]  # PlsrDAC range for TDC calibration, should start at threshold
    col_span = [55, 75]  # [50, 78]  # pixel column range to use in TDC scans
    row_span = [125, 225]  # [20, 315]  # pixel row range to use in TDC scans
    tdc_pixel = make_box_pixel_mask_from_col_row(
        column=[col_span[0], col_span[1]],
        row=[row_span[0], row_span[1]])  # edge pixel are not used in analysis

    runmngr = RunManager('configuration.yaml')

    # IV scan
    runmngr.run_run(run=IVScan,
                    run_conf={
                        "voltages": np.arange(-1, max_iv_voltage - 1, -1),
                        "max_voltage": max_iv_voltage,
                        "bias_voltage": bias_voltage,
                        "minimum_delay": 0.5
                    })

    # FE check and complete tuning
    runmngr.run_run(run=RegisterTest)
Beispiel #13
0
class HitOrCalibration(Fei4RunBase):
    ''' HitOR calibration scan
    '''
    _default_run_conf = {
        "broadcast_commands":
        True,
        "threaded_scan":
        True,
        "n_injections":
        200,  # number of injections
        "injection_delay":
        5000,  # for really low feedbacks (ToT >> 300 ns) one needs to increase the injection delay
        "scan_parameters":
        [('column', None), ('row', None),
         ('PlsrDAC',
          [40, 50, 60, 80, 130, 180, 230, 280, 340, 440, 540, 640,
           740])],  # 0 400 sufficient for most tunings
        "reset_rx_on_error":
        True,  # reset RX on errors that may occur during scan
        "pixels": (np.dstack(
            np.where(
                make_box_pixel_mask_from_col_row([40, 41], [150, 151]) == 1)) +
                   1).tolist()
        [0],  # list of (col, row) tupels. From 1 to 80/336.
        "enable_shift_masks": ["Enable", "C_Low",
                               "C_High"],  # enable masks shifted during scan
        "disable_shift_masks": ["Imon"]  # disable masks shifted during scan
    }

    def configure(self):
        commands = []
        commands.extend(self.register.get_commands("ConfMode"))
        self.register.set_global_register_value(
            "Trig_Count", 6)  # decrease trigger count to reduce data
        self.register.set_global_register_value(
            "Trig_Lat", 215)  # adjust delay for smaller bcid window
        self.register.set_global_register_value(
            "ErrorMask", 1536)  # deactivate hit bus service record
        commands.extend(
            self.register.get_commands(
                "WrRegister", name=["Trig_Lat", "Trig_Count", "ErrorMask"]))
        self.register_utils.send_commands(commands)

    def scan(self):
        def write_double_column(column):
            return (column - 1) / 2

        def inject_double_column(column):
            if column == 80:
                return 39
            else:
                return (column) / 2

        cal_lvl1_command = self.register.get_commands(
            "CAL")[0] + self.register.get_commands(
                "zeros", length=40)[0] + self.register.get_commands(
                    "LV1")[0] + self.register.get_commands(
                        "zeros", length=self.injection_delay)[0]
        scan_parameter_name = self.scan_parameters._fields[
            -1]  # scan parameter is in inner loop
        scan_parameter_values = self.scan_parameters[
            -1][:]  # create deep copy of scan_parameters, they are overwritten in self.readout

        pixels_sorted = sorted(self.pixels)  # , key=lambda tup: tup[0])
        logging.info("Scanning %d pixels" % len(self.pixels))
        # use sorted pixels to prevent overwriting of raw data file when writing a file per column
        for pixel_index, pixel in enumerate(pixels_sorted):
            if self.stop_run.is_set():
                break

            column = pixel[0]
            row = pixel[1]
            logging.info('Scanning pixel: %d / %d (column / row)', column, row)
            if pixel_index:
                dcs = [write_double_column(column)]
                dcs.append(write_double_column(self.pixels[pixel_index -
                                                           1][0]))
            else:
                dcs = []
            commands = []
            commands.extend(self.register.get_commands("ConfMode"))
            single_pixel_enable_mask = make_pixel_mask_from_col_row([column],
                                                                    [row])
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_enable_mask),
                self.enable_shift_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.enable_shift_masks,
                                           joint_write=True))
            single_pixel_disable_mask = make_pixel_mask_from_col_row([column],
                                                                     [row],
                                                                     default=1,
                                                                     value=0)
            map(
                lambda mask_name: self.register.set_pixel_register_value(
                    mask_name, single_pixel_disable_mask),
                self.disable_shift_masks)
            commands.extend(
                self.register.get_commands("WrFrontEnd",
                                           same_mask_for_all_dc=False,
                                           dcs=dcs,
                                           name=self.disable_shift_masks,
                                           joint_write=True))
            self.register.set_global_register_value(
                "Colpr_Addr", inject_double_column(column))
            commands.append(
                self.register.get_commands("WrRegister",
                                           name=["Colpr_Addr"])[0])
            self.register_utils.send_commands(commands)

            self.dut['TDC']['ENABLE'] = True
            self.dut['TDC'][
                'EN_NO_WRITE_TRIG_ERR'] = False  # Do not trigger TDC words
            for scan_parameter_value in scan_parameter_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]))
                commands.extend(self.register.get_commands("RunMode"))
                self.register_utils.send_commands(commands)

                self.dut['TDC']['EN_ARMING'] = True
                with self.readout(
                        reset_fifo=True,
                        column=column,
                        row=row,
                        **{scan_parameter_name: scan_parameter_value}):
                    self.register_utils.send_command(command=cal_lvl1_command,
                                                     repeat=self.n_injections)
                self.dut['TDC']['EN_ARMING'] = False

            self.dut['TDC']['ENABLE'] = False

    def handle_data(
            self,
            data,
            new_file=['column'],
            flush=True):  # Create new file for each scan parameter change
        super(HitOrCalibration, self).handle_data(data=data,
                                                  new_file=new_file,
                                                  flush=flush)

    def analyze(self):
        create_hitor_calibration(self.output_filename,
                                 plot_pixel_calibrations=True)